//===--- IRGenDebugInfo.cpp - Debug Info Support --------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
//  This file implements IR debug info generation for Swift.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "debug-info"
#include "polarphp/irgen/internal/IRGenDebugInfo.h"
#include "polarphp/irgen/internal/GenType.h"
#include "polarphp/ast/AstMangler.h"
#include "polarphp/ast/Expr.h"
#include "polarphp/ast/IRGenOptions.h"
#include "polarphp/ast/Module.h"
#include "polarphp/ast/ModuleLoader.h"
#include "polarphp/ast/Pattern.h"
#include "polarphp/basic/Dwarf.h"
#include "polarphp/basic/SourceMgr.h"
#include "polarphp/kernel/Version.h"
#include "polarphp/clangimporter/ClangImporter.h"
#include "polarphp/clangimporter/ClangModule.h"
#include "polarphp/demangling/ManglingMacros.h"
#include "polarphp/serialization/SerializedModuleLoader.h"
#include "polarphp/global/Config.h"
#include "polarphp/pil/lang/PILArgument.h"
#include "polarphp/pil/lang/PILBasicBlock.h"
#include "polarphp/pil/lang/PILDebugScope.h"
#include "polarphp/pil/lang/PILModule.h"
#include "clang/AST/ExternalASTSource.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Serialization/ASTReader.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/Local.h"

#ifndef NDEBUG
#include "polarphp/ast/AstDemangler.h"
#endif

using namespace polar;
using namespace irgen;

llvm::cl::opt<bool> VerifyLineTable(
   "verify-linetable", llvm::cl::init(false),
   llvm::cl::desc(
      "Verify that the debug locations within one scope are contiguous."));

namespace {
using TrackingDIRefMap =
llvm::DenseMap<const llvm::MDString *, llvm::TrackingMDNodeRef>;

class IRGenDebugInfoImpl : public IRGenDebugInfo {
   friend class IRGenDebugInfoImpl;
   const IRGenOptions &Opts;
   ClangImporter &CI;
   SourceManager &SM;
   llvm::Module &M;
   llvm::DIBuilder DBuilder;
   IRGenModule &IGM;
   const PathRemapper &DebugPrefixMap;

   /// Various caches.
   /// @{
   llvm::DenseMap<const PILDebugScope *, llvm::TrackingMDNodeRef> ScopeCache;
   llvm::DenseMap<const PILDebugScope *, llvm::TrackingMDNodeRef> InlinedAtCache;
   llvm::DenseMap<const void *, PILLocation::DebugLoc> DebugLocCache;
   llvm::DenseMap<TypeBase *, llvm::TrackingMDNodeRef> DITypeCache;
   llvm::DenseMap<const void *, llvm::TrackingMDNodeRef> DIModuleCache;
   llvm::StringMap<llvm::TrackingMDNodeRef> DIFileCache;
   TrackingDIRefMap DIRefMap;
   /// @}

   /// A list of replaceable fwddecls that need to be RAUWed at the end.
   std::vector<std::pair<TypeBase *, llvm::TrackingMDRef>> ReplaceMap;
   /// The set of imported modules.
   llvm::DenseSet<ModuleDecl *> ImportedModules;

   llvm::BumpPtrAllocator DebugInfoNames;
   /// The current working directory.
   StringRef CWDName;
   /// User-provided -D macro definitions.
   SmallString<0> ConfigMacros;
   /// The current compilation unit.
   llvm::DICompileUnit *TheCU = nullptr;
   /// The main file.
   llvm::DIFile *MainFile = nullptr;
   /// The current module.
   llvm::DIModule *MainModule = nullptr;
   /// Scope of SWIFT_ENTRY_POINT_FUNCTION.
   llvm::DIScope *EntryPointFn = nullptr;
   /// The artificial type decls for named archetypes.
   llvm::StringMap<TypeAliasDecl *> MetadataTypeDeclCache;
   /// Catch-all type for opaque internal types.
   llvm::DIType *InternalType = nullptr;

   /// The last location that was emitted.
   PILLocation::DebugLoc LastDebugLoc;
   /// The scope of that last location.
   const PILDebugScope *LastScope = nullptr;

   /// Used by pushLoc.
   SmallVector<std::pair<PILLocation::DebugLoc, const PILDebugScope *>, 8>
      LocationStack;

#ifndef NDEBUG
   using UUSTuple = std::pair<std::pair<unsigned, unsigned>, StringRef>;
   struct DebugLocKey : public UUSTuple {
      DebugLocKey(PILLocation::DebugLoc DL)
         : UUSTuple({{DL.Line, DL.Column}, DL.Filename}) {}
      inline bool operator==(const PILLocation::DebugLoc &DL) const {
         return first.first == DL.Line && first.second == DL.Column &&
                second.equals(DL.Filename);
      }
   };
   llvm::DenseSet<UUSTuple> PreviousLineEntries;
   PILLocation::DebugLoc PreviousDebugLoc;
#endif

public:
   IRGenDebugInfoImpl(const IRGenOptions &Opts, ClangImporter &CI,
                      IRGenModule &IGM, llvm::Module &M,
                      StringRef MainOutputFilenameForDebugInfo);
   void finalize();

   void setCurrentLoc(IRBuilder &Builder, const PILDebugScope *DS,
                      PILLocation Loc);

   void addFailureMessageToCurrentLoc(IRBuilder &Builder, StringRef failureMsg);

   void clearLoc(IRBuilder &Builder);
   void pushLoc();
   void popLoc();
   void setInlinedTrapLocation(IRBuilder &Builder, const PILDebugScope *Scope);
   void setEntryPointLoc(IRBuilder &Builder);
   llvm::DIScope *getEntryPointFn();
   llvm::DIScope *getOrCreateScope(const PILDebugScope *DS);
   void emitImport(ImportDecl *D);
   llvm::DISubprogram *emitFunction(const PILDebugScope *DS, llvm::Function *Fn,
                                    PILFunctionTypeRepresentation Rep,
                                    PILType Ty, DeclContext *DeclCtx = nullptr);
   llvm::DISubprogram *emitFunction(PILFunction &PILFn, llvm::Function *Fn);
   void emitArtificialFunction(IRBuilder &Builder, llvm::Function *Fn,
                               PILType PILTy);
   void emitVariableDeclaration(IRBuilder &Builder,
                                ArrayRef<llvm::Value *> Storage,
                                DebugTypeInfo Ty, const PILDebugScope *DS,
                                ValueDecl *VarDecl, PILDebugVariable VarInfo,
                                IndirectionKind = DirectValue,
                                ArtificialKind = RealValue);
   void emitDbgIntrinsic(IRBuilder &Builder, llvm::Value *Storage,
                         llvm::DILocalVariable *Var, llvm::DIExpression *Expr,
                         unsigned Line, unsigned Col, llvm::DILocalScope *Scope,
                         const PILDebugScope *DS);
   void emitGlobalVariableDeclaration(llvm::GlobalVariable *Storage,
                                      StringRef Name, StringRef LinkageName,
                                      DebugTypeInfo DebugType,
                                      bool IsLocalToUnit, bool InFixedBuffer,
                                      Optional<PILLocation> Loc);
   void emitTypeMetadata(IRGenFunction &IGF, llvm::Value *Metadata,
                         unsigned Depth, unsigned Index, StringRef Name);

   /// Return the DIBuilder.
   llvm::DIBuilder &getBuilder() { return DBuilder; }

   /// Decode (and cache) a SourceLoc.
   PILLocation::DebugLoc decodeSourceLoc(SourceLoc SL);

   IRGenDebugInfoFormat getDebugInfoFormat() { return Opts.DebugInfoFormat; }

private:
   static StringRef getFilenameFromDC(const DeclContext *DC) {
      if (auto *LF = dyn_cast<LoadedFile>(DC))
         return LF->getFilename();
      if (auto *SF = dyn_cast<SourceFile>(DC))
         return SF->getFilename();
      if (auto *M = dyn_cast<ModuleDecl>(DC))
         return M->getModuleFilename();
      return {};
   }

   using DebugLoc = PILLocation::DebugLoc;
   DebugLoc getDeserializedLoc(Pattern *) { return {}; }
   DebugLoc getDeserializedLoc(Expr *) { return {}; }
   DebugLoc getDeserializedLoc(Decl *D) {
      DebugLoc L;
      const DeclContext *DC = D->getDeclContext()->getModuleScopeContext();
      StringRef Filename = getFilenameFromDC(DC);
      if (!Filename.empty())
         L.Filename = Filename;
      return L;
   }

   /// Use the Polarphp SM to figure out the actual line/column of a SourceLoc.
   template <typename WithLoc>
   DebugLoc getSwiftDebugLoc(IRGenDebugInfo &DI, WithLoc *ASTNode, bool End) {
      if (!ASTNode)
         return {};

      SourceLoc Loc = End ? ASTNode->getEndLoc() : ASTNode->getStartLoc();
      if (Loc.isInvalid())
         // This may be a deserialized or clang-imported decl. And modules
         // don't come with SourceLocs right now. Get at least the name of
         // the module.
         return getDeserializedLoc(ASTNode);

      return DI.decodeSourceLoc(Loc);
   }

   DebugLoc getDebugLoc(IRGenDebugInfo &DI, Pattern *P, bool End = false) {
      return getSwiftDebugLoc(DI, P, End);
   }
   DebugLoc getDebugLoc(IRGenDebugInfo &DI, Expr *E, bool End = false) {
      return getSwiftDebugLoc(DI, E, End);
   }
   DebugLoc getDebugLoc(IRGenDebugInfo &DI, Decl *D, bool End = false) {
      DebugLoc L;
      if (!D)
         return L;

      if (auto *ClangDecl = D->getClangDecl()) {
         clang::SourceLocation ClangSrcLoc = ClangDecl->getBeginLoc();
         clang::SourceManager &ClangSM =
            CI.getClangAstContext().getSourceManager();
         clang::PresumedLoc PresumedLoc = ClangSM.getPresumedLoc(ClangSrcLoc);
         if (!PresumedLoc.isValid())
            return L;
         L.Line = PresumedLoc.getLine();
         L.Column = PresumedLoc.getColumn();
         L.Filename = PresumedLoc.getFilename();
         return L;
      }
      return getSwiftDebugLoc(DI, D, End);
   }

   DebugLoc getStartLocation(Optional<PILLocation> OptLoc) {
      if (!OptLoc)
         return {};
      return decodeSourceLoc(OptLoc->getStartSourceLoc());
   }

   DebugLoc sanitizeCodeViewDebugLoc(DebugLoc DLoc) {
      if (Opts.DebugInfoFormat == IRGenDebugInfoFormat::CodeView)
         // When WinDbg finds two locations with the same line but different
         // columns, the user must select an address when they break on that
         // line. Also, clang does not emit column locations in CodeView for C++.
         DLoc.Column = 0;
      return DLoc;
   }

   DebugLoc decodeDebugLoc(PILLocation Loc) {
      if (Loc.isDebugInfoLoc())
         return sanitizeCodeViewDebugLoc(Loc.getDebugInfoLoc());
      return decodeSourceLoc(Loc.getDebugSourceLoc());
   }

   DebugLoc getDebugLocation(Optional<PILLocation> OptLoc) {
      if (!OptLoc || (Opts.DebugInfoFormat != IRGenDebugInfoFormat::CodeView &&
                      OptLoc->isInPrologue()))
         return {};
      return decodeDebugLoc(*OptLoc);
   }

   /// Strdup a raw char array using the bump pointer.
   StringRef BumpAllocatedString(const char *Data, size_t Length) {
      char *Ptr = DebugInfoNames.Allocate<char>(Length + 1);
      memcpy(Ptr, Data, Length);
      *(Ptr + Length) = 0;
      return StringRef(Ptr, Length);
   }

   /// Strdup S using the bump pointer.
   StringRef BumpAllocatedString(std::string S) {
      return BumpAllocatedString(S.c_str(), S.length());
   }

   /// Strdup StringRef S using the bump pointer.
   StringRef BumpAllocatedString(StringRef S) {
      return BumpAllocatedString(S.data(), S.size());
   }

   /// Return the size reported by a type.
   static unsigned getSizeInBits(llvm::DIType *Ty) {
      // Follow derived types until we reach a type that
      // reports back a size.
      while (isa<llvm::DIDerivedType>(Ty) && !Ty->getSizeInBits()) {
         auto *DT = cast<llvm::DIDerivedType>(Ty);
         Ty = DT->getBaseType();
         if (!Ty)
            return 0;
      }
      return Ty->getSizeInBits();
   }

#ifndef NDEBUG

   /// Return the size reported by the variable's type.
   static unsigned getSizeInBits(const llvm::DILocalVariable *Var) {
      llvm::DIType *Ty = Var->getType();
      return getSizeInBits(Ty);
   }

#endif

   /// Determine whether this debug scope belongs to an explicit closure.
   static bool isExplicitClosure(const PILFunction *PILFn) {
      if (PILFn && PILFn->hasLocation())
         if (Expr *E = PILFn->getLocation().getAsAstNode<Expr>())
            if (isa<ClosureExpr>(E))
               return true;
      return false;
   }

   llvm::MDNode *createInlinedAt(const PILDebugScope *DS) {
      auto *CS = DS->InlinedCallSite;
      if (!CS)
         return nullptr;

      auto CachedInlinedAt = InlinedAtCache.find(CS);
      if (CachedInlinedAt != InlinedAtCache.end())
         return cast<llvm::MDNode>(CachedInlinedAt->second);

      auto L = decodeDebugLoc(CS->Loc);
      auto Scope = getOrCreateScope(CS->Parent.dyn_cast<const PILDebugScope *>());
      // Pretend transparent functions don't exist.
      if (!Scope)
         return createInlinedAt(CS);
      auto InlinedAt =
         llvm::DebugLoc::get(L.Line, L.Column, Scope, createInlinedAt(CS));
      InlinedAtCache.insert(
         {CS, llvm::TrackingMDNodeRef(InlinedAt.getAsMDNode())});
      return InlinedAt;
   }

#ifndef NDEBUG
   /// Perform a couple of sanity checks on scopes.
   static bool parentScopesAreSane(const PILDebugScope *DS) {
      auto *Parent = DS;
      while ((Parent = Parent->Parent.dyn_cast<const PILDebugScope *>())) {
         if (!DS->InlinedCallSite)
            assert(!Parent->InlinedCallSite &&
                   "non-inlined scope has an inlined parent");
      }
      return true;
   }

   /// Assert that within one lexical block, each location is only visited once.
   bool lineEntryIsSane(PILLocation::DebugLoc DL, const PILDebugScope *DS);

#endif

   llvm::DIFile *getOrCreateFile(StringRef Filename) {
      if (Filename.empty())
         Filename = PILLocation::getCompilerGeneratedDebugLoc().Filename;

      // Look in the cache first.
      auto CachedFile = DIFileCache.find(Filename);
      if (CachedFile != DIFileCache.end()) {
         // Verify that the information still exists.
         if (llvm::Metadata *V = CachedFile->second)
            return cast<llvm::DIFile>(V);
      }

      // Detect the main file.
      StringRef MainFileName = MainFile->getFilename();
      if (MainFile && Filename.endswith(MainFileName)) {
         SmallString<256> AbsThisFile, AbsMainFile;
         AbsThisFile = Filename;
         llvm::sys::fs::make_absolute(AbsThisFile);
         if (llvm::sys::path::is_absolute(MainFileName))
            AbsMainFile = MainFileName;
         else
            llvm::sys::path::append(AbsMainFile, MainFile->getDirectory(),
                                    MainFileName);
         if (AbsThisFile == DebugPrefixMap.remapPath(AbsMainFile)) {
            DIFileCache[Filename] = llvm::TrackingMDNodeRef(MainFile);
            return MainFile;
         }
      }

      return createFile(Filename, None, None);
   }

   /// This is effectively \p clang::CGDebugInfo::createFile().
   llvm::DIFile *
   createFile(StringRef FileName,
              Optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo,
              Optional<StringRef> Source) {
      StringRef Dir;
      StringRef File;
      SmallString<128> DirBuf;
      SmallString<128> FileBuf;
      std::string RemappedFileString = DebugPrefixMap.remapPath(FileName);
      SmallString<128> RemappedFile = StringRef(RemappedFileString);
      llvm::sys::path::remove_dots(RemappedFile);
      std::string CurDir = DebugPrefixMap.remapPath(Opts.DebugCompilationDir);
      if (llvm::sys::path::is_absolute(RemappedFile)) {
         // Strip the common prefix (if it is more than just "/") from current
         // directory and FileName for a more space-efficient encoding.
         auto FileIt = llvm::sys::path::begin(RemappedFile);
         auto FileE = llvm::sys::path::end(RemappedFile);
         auto CurDirIt = llvm::sys::path::begin(CurDir);
         auto CurDirE = llvm::sys::path::end(CurDir);
         for (; CurDirIt != CurDirE && *CurDirIt == *FileIt; ++CurDirIt, ++FileIt)
            llvm::sys::path::append(DirBuf, *CurDirIt);
         if (std::distance(llvm::sys::path::begin(CurDir), CurDirIt) == 1) {
            // Don't strip the common prefix if it is only the root "/"
            // since that would make LLVM diagnostic locations confusing.
            Dir = {};
            File = RemappedFile;
         } else {
            for (; FileIt != FileE; ++FileIt)
               llvm::sys::path::append(FileBuf, *FileIt);
            Dir = DirBuf;
            File = FileBuf;
         }
      } else {
         File = RemappedFile;
         // Leave <compiler-generated> & friends as is, without directory.
         if (!(File.startswith("<") && File.endswith(">")))
            Dir = CurDir;
      }
      llvm::DIFile *F = DBuilder.createFile(File, Dir, CSInfo, Source);
      DIFileCache[FileName].reset(F);
      return F;
   }

   StringRef getName(const FuncDecl &FD) {
      // Getters and Setters are anonymous functions, so we forge a name
      // using its parent declaration.
      if (auto accessor = dyn_cast<AccessorDecl>(&FD))
         if (ValueDecl *VD = accessor->getStorage()) {
            const char *Kind;
            switch (accessor->getAccessorKind()) {
               case AccessorKind::Get:
                  Kind = ".get";
                  break;
               case AccessorKind::Set:
                  Kind = ".set";
                  break;
               case AccessorKind::WillSet:
                  Kind = ".willset";
                  break;
               case AccessorKind::DidSet:
                  Kind = ".didset";
                  break;
               case AccessorKind::Address:
                  Kind = ".addressor";
                  break;
               case AccessorKind::MutableAddress:
                  Kind = ".mutableAddressor";
                  break;
               case AccessorKind::Read:
                  Kind = ".read";
                  break;
               case AccessorKind::Modify:
                  Kind = ".modify";
                  break;
            }

            SmallVector<char, 64> Buf;
            StringRef Name = (VD->getBaseName().userFacingName() +
                              Twine(Kind)).toStringRef(Buf);
            return BumpAllocatedString(Name);
         }

      if (FD.hasName())
         return FD.getName().str();

      return StringRef();
   }

   StringRef getName(PILLocation L) {
      if (L.isNull())
         return StringRef();

      if (FuncDecl *FD = L.getAsAstNode<FuncDecl>())
         return getName(*FD);

      if (L.isAstNode<ConstructorDecl>())
         return "init";

      if (L.isAstNode<DestructorDecl>())
         return "deinit";

      return StringRef();
   }

   static CanPILFunctionType getFunctionType(PILType PILTy) {
      if (!PILTy)
         return CanPILFunctionType();

      auto FnTy = PILTy.getAs<PILFunctionType>();
      if (!FnTy) {
         LLVM_DEBUG(llvm::dbgs() << "Unexpected function type: ";
                       PILTy.print(llvm::dbgs());
                       llvm::dbgs() << "\n");
         return CanPILFunctionType();
      }

      return FnTy;
   }

   llvm::DIScope *getOrCreateContext(DeclContext *DC) {
      if (!DC)
         return TheCU;

      if (isa<FuncDecl>(DC))
         if (auto *Decl = IGM.getPILModule().lookUpFunction(PILDeclRef(
            cast<AbstractFunctionDecl>(DC), PILDeclRef::Kind::Func)))
            return getOrCreateScope(Decl->getDebugScope());

      switch (DC->getContextKind()) {
         // The interesting cases are already handled above.
         case DeclContextKind::AbstractFunctionDecl:
         case DeclContextKind::AbstractClosureExpr:

            // We don't model these in DWARF.
         case DeclContextKind::SerializedLocal:
         case DeclContextKind::Initializer:
         case DeclContextKind::ExtensionDecl:
         case DeclContextKind::SubscriptDecl:
         case DeclContextKind::EnumElementDecl:
         case DeclContextKind::TopLevelCodeDecl:
            return getOrCreateContext(DC->getParent());

         case DeclContextKind::Module:
            return getOrCreateModule(
               {ModuleDecl::AccessPathTy(), cast<ModuleDecl>(DC)});
         case DeclContextKind::FileUnit:
            // A module may contain multiple files.
            return getOrCreateContext(DC->getParent());
         case DeclContextKind::GenericTypeDecl: {
            auto *NTD = cast<NominalTypeDecl>(DC);
            auto *Ty = NTD->getDeclaredType().getPointer();
            if (auto *DITy = getTypeOrNull(Ty))
               return DITy;

            // Create a Forward-declared type.
            auto Loc = getDebugLoc(*this, NTD);
            auto File = getOrCreateFile(Loc.Filename);
            auto Line = Loc.Line;
            auto FwdDecl = DBuilder.createReplaceableCompositeType(
               llvm::dwarf::DW_TAG_structure_type, NTD->getName().str(),
               getOrCreateContext(DC->getParent()), File, Line,
               llvm::dwarf::DW_LANG_Swift, 0, 0);
            ReplaceMap.emplace_back(
               std::piecewise_construct, std::make_tuple(Ty),
               std::make_tuple(static_cast<llvm::Metadata *>(FwdDecl)));
            return FwdDecl;
         }
      }
      return TheCU;
   }

   void createParameterType(llvm::SmallVectorImpl<llvm::Metadata *> &Parameters,
                            PILType type) {
      auto RealType = type.getAstType();
      auto DbgTy = DebugTypeInfo::getFromTypeInfo(RealType, IGM.getTypeInfo(type));
      Parameters.push_back(getOrCreateType(DbgTy));
   }

   // This is different from PILFunctionType::getAllResultsType() in some subtle
   // ways.
   static PILType getResultTypeForDebugInfo(IRGenModule &IGM,
                                            CanPILFunctionType fnTy) {
      if (fnTy->getNumResults() == 1) {
         return fnTy->getResults()[0].getPILStorageType(IGM.getPILModule(), fnTy);
      } else if (!fnTy->getNumIndirectFormalResults()) {
         return fnTy->getDirectFormalResultsType(IGM.getPILModule());
      } else {
         SmallVector<TupleTypeElt, 4> eltTys;
         for (auto &result : fnTy->getResults()) {
            eltTys.push_back(result.getReturnValueType(IGM.getPILModule(), fnTy));
         }
         return PILType::getPrimitiveAddressType(
            CanType(TupleType::get(eltTys, fnTy->getAstContext())));
      }
   }

   llvm::DITypeRefArray createParameterTypes(PILType PILTy) {
      if (!PILTy)
         return nullptr;
      return createParameterTypes(PILTy.castTo<PILFunctionType>());
   }

   llvm::DITypeRefArray createParameterTypes(CanPILFunctionType FnTy) {
      SmallVector<llvm::Metadata *, 16> Parameters;

      GenericContextScope scope(IGM, FnTy->getInvocationGenericSignature());

      // The function return type is the first element in the list.
      createParameterType(Parameters, getResultTypeForDebugInfo(IGM, FnTy));

      // Actually, the input type is either a single type or a tuple
      // type. We currently represent a function with one n-tuple argument
      // as an n-ary function.
      for (auto Param : FnTy->getParameters())
         createParameterType(Parameters, IGM.silConv.getPILType(Param, FnTy));

      return DBuilder.getOrCreateTypeArray(Parameters);
   }

   /// FIXME: replace this condition with something more sane.
   static bool isAllocatingConstructor(PILFunctionTypeRepresentation Rep,
                                       DeclContext *DeclCtx) {
      return Rep != PILFunctionTypeRepresentation::Method && DeclCtx &&
             isa<ConstructorDecl>(DeclCtx);
   }

   llvm::DIModule *getOrCreateModule(const void *Key, llvm::DIScope *Parent,
                                     StringRef Name, StringRef IncludePath,
                                     uint64_t Signature = ~1ULL,
                                     StringRef ASTFile = StringRef()) {
      // Look in the cache first.
      auto Val = DIModuleCache.find(Key);
      if (Val != DIModuleCache.end())
         return cast<llvm::DIModule>(Val->second);

      std::string RemappedIncludePath = DebugPrefixMap.remapPath(IncludePath);

      // For Clang modules / PCH, create a Skeleton CU pointing to the PCM/PCH.
      if (!Opts.DisableClangModuleSkeletonCUs) {
         bool CreateSkeletonCU = !ASTFile.empty();
         bool IsRootModule = !Parent;
         if (CreateSkeletonCU && IsRootModule) {
            llvm::DIBuilder DIB(M);
            DIB.createCompileUnit(IGM.ObjCInterop ? llvm::dwarf::DW_LANG_ObjC
                                                  : llvm::dwarf::DW_LANG_C99,
                                  DIB.createFile(Name, RemappedIncludePath),
                                  TheCU->getProducer(), true, StringRef(), 0,
                                  ASTFile, llvm::DICompileUnit::FullDebug,
                                  Signature);
            DIB.finalize();
         }
      }

      StringRef Sysroot = IGM.Context.SearchPathOpts.SDKPath;
      llvm::DIModule *M =
         DBuilder.createModule(Parent, Name, ConfigMacros, RemappedIncludePath,
                               Sysroot);
      DIModuleCache.insert({Key, llvm::TrackingMDNodeRef(M)});
      return M;
   }

   using ASTSourceDescriptor = clang::ExternalASTSource::ASTSourceDescriptor;
   /// Create a DIModule from a clang module or PCH.
   /// The clang::Module pointer is passed separately because the recursive case
   /// needs to fudge the AST descriptor.
   llvm::DIModule *getOrCreateModule(ASTSourceDescriptor Desc,
                                     const clang::Module *ClangModule) {
      // PCH files don't have a signature field in the control block,
      // but LLVM detects skeleton CUs by looking for a non-zero DWO id.
      // We use the lower 64 bits for debug info.
      uint64_t Signature =
         Desc.getSignature()
         ? (uint64_t)Desc.getSignature()[1] << 32 | Desc.getSignature()[0]
         : ~1ULL;

      // Handle Clang modules.
      if (ClangModule) {
         llvm::DIModule *Parent = nullptr;
         if (ClangModule->Parent) {
            // The loading of additional modules by Sema may trigger an out-of-date
            // PCM rebuild in the Clang module dependencies of the additional
            // module. A PCM rebuild causes the ModuleManager to unload previously
            // loaded ASTFiles. For this reason we must use the cached ASTFile
            // information here instead of the potentially dangling pointer to the
            // ASTFile that is stored in the clang::Module object.
            //
            // Note: The implementation here assumes that all clang submodules
            //       belong to the same PCM file.
            ASTSourceDescriptor ParentDescriptor(*ClangModule->Parent);
            Parent = getOrCreateModule({ParentDescriptor.getModuleName(),
                                        ParentDescriptor.getPath(),
                                        Desc.getASTFile(), Desc.getSignature()},
                                       ClangModule->Parent);
         }
         return getOrCreateModule(ClangModule, Parent, Desc.getModuleName(),
                                  Desc.getPath(), Signature, Desc.getASTFile());
      }
      // Handle PCH.
      return getOrCreateModule(Desc.getASTFile().bytes_begin(), nullptr,
                               Desc.getModuleName(), Desc.getPath(), Signature,
                               Desc.getASTFile());
   };

   static Optional<ASTSourceDescriptor> getClangModule(const ModuleDecl &M) {
      for (auto *FU : M.getFiles())
         if (auto *CMU = dyn_cast_or_null<ClangModuleUnit>(FU))
            if (auto Desc = CMU->getAstSourceDescriptor())
               return Desc;
      return None;
   }

   llvm::DIModule *getOrCreateModule(ModuleDecl::ImportedModule IM) {
      ModuleDecl *M = IM.second;
      if (Optional<ASTSourceDescriptor> ModuleDesc = getClangModule(*M))
         return getOrCreateModule(*ModuleDesc, ModuleDesc->getModuleOrNull());
      StringRef Path = getFilenameFromDC(M);
      StringRef Name = M->getName().str();
      return getOrCreateModule(M, TheCU, Name, Path);
   }

   TypeAliasDecl *getMetadataType(StringRef ArchetypeName) {
      TypeAliasDecl *&Entry = MetadataTypeDeclCache[ArchetypeName];
      if (Entry)
         return Entry;

      SourceLoc NoLoc;
      Entry = new (IGM.Context) TypeAliasDecl(
         NoLoc, NoLoc, IGM.Context.getIdentifier(ArchetypeName), NoLoc,
         /*genericparams*/ nullptr, IGM.Context.TheBuiltinModule);
      Entry->setUnderlyingType(IGM.Context.TheRawPointerType);
      return Entry;
   }

   /// Return the DIFile that is the ancestor of Scope.
   llvm::DIFile *getFile(llvm::DIScope *Scope) {
      while (!isa<llvm::DIFile>(Scope)) {
         switch (Scope->getTag()) {
            case llvm::dwarf::DW_TAG_lexical_block:
               Scope = cast<llvm::DILexicalBlock>(Scope)->getScope();
               break;
            case llvm::dwarf::DW_TAG_subprogram:
               Scope = cast<llvm::DISubprogram>(Scope)->getFile();
               break;
            default:
               return MainFile;
         }
         if (Scope)
            return MainFile;
      }
      return cast<llvm::DIFile>(Scope);
   }

   static Size getStorageSize(const llvm::DataLayout &DL,
                              ArrayRef<llvm::Value *> Storage) {
      unsigned size = 0;
      for (llvm::Value *Piece : Storage)
         size += DL.getTypeSizeInBits(Piece->getType());
      return Size(size);
   }

   StringRef getMangledName(DebugTypeInfo DbgTy) {
      if (DbgTy.IsMetadataType)
         return MetadataTypeDeclCache.find(DbgTy.getDecl()->getName().str())
            ->getKey();

      Type Ty = DbgTy.getType();
      if (!Ty->hasTypeParameter())
         Ty = Ty->mapTypeOutOfContext();

      // Strip off top level of type sugar (except for type aliases).
      // We don't want Optional<T> and T? to get different debug types.
      while (true) {
         if (auto *ParenTy = dyn_cast<ParenType>(Ty.getPointer())) {
            Ty = ParenTy->getUnderlyingType();
            continue;
         }

         if (auto *SugarTy = dyn_cast<SyntaxSugarType>(Ty.getPointer())) {
            Ty = SugarTy->getSinglyDesugaredType();
            continue;
         }

         break;
      }

      mangle::AstMangler Mangler;
      std::string Result = Mangler.mangleTypeForDebugger(
         Ty, nullptr);

      if (!Opts.DisableRoundTripDebugTypes
          // FIXME: implement type reconstruction for opaque types
          && !Ty->hasOpaqueArchetype()) {
         // Make sure we can reconstruct mangled types for the debugger.
#ifndef NDEBUG
         auto &Ctx = Ty->getAstContext();
         Type Reconstructed = demangling::getTypeForMangling(Ctx, Result);
         if (!Reconstructed) {
            llvm::errs() << "Failed to reconstruct type for " << Result << "\n";
            llvm::errs() << "Original type:\n";
            Ty->dump(llvm::errs());
            abort();
         } else if (!Reconstructed->isEqual(Ty)) {
            llvm::errs() << "Incorrect reconstructed type for " << Result << "\n";
            llvm::errs() << "Original type:\n";
            Ty->dump(llvm::errs());
            llvm::errs() << "Reconstructed type:\n";
            Reconstructed->dump(llvm::errs());
            abort();
         }
#endif
      }

      return BumpAllocatedString(Result);
   }

   llvm::DIDerivedType *createMemberType(DebugTypeInfo DbgTy, StringRef Name,
                                         unsigned &OffsetInBits,
                                         llvm::DIScope *Scope,
                                         llvm::DIFile *File,
                                         llvm::DINode::DIFlags Flags) {
      unsigned SizeOfByte = CI.getTargetInfo().getCharWidth();
      auto *Ty = getOrCreateType(DbgTy);
      auto *DITy = DBuilder.createMemberType(Scope, Name, File, 0,
                                             SizeOfByte * DbgTy.size.getValue(),
                                             0, OffsetInBits, Flags, Ty);
      OffsetInBits += getSizeInBits(Ty);
      OffsetInBits =
         llvm::alignTo(OffsetInBits, SizeOfByte * DbgTy.align.getValue());
      return DITy;
   }

   llvm::DINodeArray
   getTupleElements(TupleType *TupleTy, llvm::DIScope *Scope, llvm::DIFile *File,
                    llvm::DINode::DIFlags Flags, unsigned &SizeInBits) {
      SmallVector<llvm::Metadata *, 16> Elements;
      unsigned OffsetInBits = 0;
      auto genericSig = IGM.getCurGenericContext();
      for (auto ElemTy : TupleTy->getElementTypes()) {
         auto &elemTI = IGM.getTypeInfoForUnlowered(
            AbstractionPattern(genericSig, ElemTy->getCanonicalType()), ElemTy);
         auto DbgTy =
            DebugTypeInfo::getFromTypeInfo(ElemTy, elemTI);
         Elements.push_back(createMemberType(DbgTy, StringRef(), OffsetInBits,
                                             Scope, File, Flags));
      }
      SizeInBits = OffsetInBits;
      return DBuilder.getOrCreateArray(Elements);
   }

   llvm::DINodeArray getStructMembers(NominalTypeDecl *D, Type BaseTy,
                                      llvm::DIScope *Scope, llvm::DIFile *File,
                                      llvm::DINode::DIFlags Flags,
                                      unsigned &SizeInBits) {
      SmallVector<llvm::Metadata *, 16> Elements;
      unsigned OffsetInBits = 0;
      for (VarDecl *VD : D->getStoredProperties()) {
         auto memberTy =
            BaseTy->getTypeOfMember(IGM.getPolarphpModule(), VD, nullptr);

         auto DbgTy = DebugTypeInfo::getFromTypeInfo(
            VD->getInterfaceType(),
            IGM.getTypeInfoForUnlowered(
               IGM.getPILTypes().getAbstractionPattern(VD), memberTy));
         Elements.push_back(createMemberType(DbgTy, VD->getName().str(),
                                             OffsetInBits, Scope, File, Flags));
      }
      if (OffsetInBits > SizeInBits)
         SizeInBits = OffsetInBits;
      return DBuilder.getOrCreateArray(Elements);
   }

   llvm::DICompositeType *
   createStructType(DebugTypeInfo DbgTy, NominalTypeDecl *Decl, Type BaseTy,
                    llvm::DIScope *Scope, llvm::DIFile *File, unsigned Line,
                    unsigned SizeInBits, unsigned AlignInBits,
                    llvm::DINode::DIFlags Flags, llvm::DIType *DerivedFrom,
                    unsigned RuntimeLang, StringRef UniqueID) {
      StringRef Name = Decl->getName().str();

      // Forward declare this first because types may be recursive.
      auto FwdDecl = llvm::TempDIType(DBuilder.createReplaceableCompositeType(
         llvm::dwarf::DW_TAG_structure_type, Name, Scope, File, Line,
         llvm::dwarf::DW_LANG_Swift, SizeInBits, 0, Flags, UniqueID));

#ifndef NDEBUG
      if (UniqueID.empty())
         assert(!Name.empty() &&
                "no mangled name and no human readable name given");
      else
         assert((UniqueID.startswith("_T") ||
                 UniqueID.startswith(MANGLING_PREFIX_STR)) &&
                "UID is not a mangled name");
#endif

      auto TH = llvm::TrackingMDNodeRef(FwdDecl.get());
      DITypeCache[DbgTy.getType()] = TH;
      auto Members =
         getStructMembers(Decl, BaseTy, Scope, File, Flags, SizeInBits);
      auto DITy = DBuilder.createStructType(
         Scope, Name, File, Line, SizeInBits, AlignInBits, Flags, DerivedFrom,
         Members, RuntimeLang, nullptr, UniqueID);
      DBuilder.replaceTemporary(std::move(FwdDecl), DITy);
      return DITy;
   }

   llvm::DINodeArray getEnumElements(DebugTypeInfo DbgTy, EnumDecl *ED,
                                     llvm::DIScope *Scope, llvm::DIFile *File,
                                     llvm::DINode::DIFlags Flags) {
      SmallVector<llvm::Metadata *, 16> Elements;

      for (auto *ElemDecl : ED->getAllElements()) {
         // FIXME <rdar://problem/14845818> Support enums.
         // Swift Enums can be both like DWARF enums and discriminated unions.
         DebugTypeInfo ElemDbgTy;
         if (ED->hasRawType())
            // An enum with a raw type (enum E : Int {}), similar to a
            // DWARF enum.
            //
            // The storage occupied by the enum may be smaller than the
            // one of the raw type as long as it is large enough to hold
            // all enum values. Use the raw type for the debug type, but
            // the storage size from the enum.
            ElemDbgTy = DebugTypeInfo(ED->getRawType(), DbgTy.StorageType,
                                      DbgTy.size, DbgTy.align, true, false);
         else if (auto ArgTy = ElemDecl->getArgumentInterfaceType()) {
            // A discriminated union. This should really be described as a
            // DW_TAG_variant_type. For now only describing the data.
            ArgTy = ElemDecl->getParentEnum()->mapTypeIntoContext(ArgTy);
            auto &TI = IGM.getTypeInfoForUnlowered(ArgTy);
            ElemDbgTy = DebugTypeInfo::getFromTypeInfo(ArgTy, TI);
         } else {
            // Discriminated union case without argument. Fallback to Int
            // as the element type; there is no storage here.
            Type IntTy = IGM.Context.getIntDecl()->getDeclaredType();
            ElemDbgTy = DebugTypeInfo(IntTy, DbgTy.StorageType, Size(0),
                                      Alignment(1), true, false);
         }
         unsigned Offset = 0;
         auto MTy = createMemberType(ElemDbgTy, ElemDecl->getName().str(), Offset,
                                     Scope, File, Flags);
         Elements.push_back(MTy);
      }
      return DBuilder.getOrCreateArray(Elements);
   }

   llvm::DICompositeType *createEnumType(DebugTypeInfo DbgTy, EnumDecl *Decl,
                                         StringRef MangledName,
                                         llvm::DIScope *Scope,
                                         llvm::DIFile *File, unsigned Line,
                                         llvm::DINode::DIFlags Flags) {
      unsigned SizeOfByte = CI.getTargetInfo().getCharWidth();
      unsigned SizeInBits = DbgTy.size.getValue() * SizeOfByte;
      // Default, since Swift doesn't allow specifying a custom alignment.
      unsigned AlignInBits = 0;

      // FIXME: Is DW_TAG_union_type the right thing here?
      // Consider using a DW_TAG_variant_type instead.
      auto FwdDecl = llvm::TempDIType(DBuilder.createReplaceableCompositeType(
         llvm::dwarf::DW_TAG_union_type, MangledName, Scope, File, Line,
         llvm::dwarf::DW_LANG_Swift, SizeInBits, AlignInBits, Flags,
         MangledName));

      auto TH = llvm::TrackingMDNodeRef(FwdDecl.get());
      DITypeCache[DbgTy.getType()] = TH;

      auto DITy = DBuilder.createUnionType(
         Scope, Decl->getName().str(), File, Line, SizeInBits, AlignInBits,
         Flags, getEnumElements(DbgTy, Decl, Scope, File, Flags),
         llvm::dwarf::DW_LANG_Swift, MangledName);

      DBuilder.replaceTemporary(std::move(FwdDecl), DITy);
      return DITy;
   }

   llvm::DIType *getOrCreateDesugaredType(Type Ty, DebugTypeInfo DbgTy) {
      DebugTypeInfo BlandDbgTy(Ty, DbgTy.StorageType, DbgTy.size, DbgTy.align,
                               DbgTy.DefaultAlignment, DbgTy.IsMetadataType);
      return getOrCreateType(BlandDbgTy);
   }

   uint64_t getSizeOfBasicType(DebugTypeInfo DbgTy) {
      uint64_t SizeOfByte = CI.getTargetInfo().getCharWidth();
      uint64_t BitWidth = DbgTy.size.getValue() * SizeOfByte;
      llvm::Type *StorageType = DbgTy.StorageType
                                ? DbgTy.StorageType
                                : IGM.DataLayout.getSmallestLegalIntType(
            IGM.getLLVMContext(), BitWidth);

      if (StorageType)
         return IGM.DataLayout.getTypeSizeInBits(StorageType);

      // This type is too large to fit in a register.
      assert(BitWidth > IGM.DataLayout.getLargestLegalIntTypeSizeInBits());
      return BitWidth;
   }

   /// Create a sized container for a sizeless type. Used to represent
   /// BoundGenericEnums that may have different sizes depending on what they are
   /// bound to, but still share a mangled name.
   llvm::DIType *createOpaqueStructWithSizedContainer(
      llvm::DIScope *Scope, StringRef Name, llvm::DIFile *File, unsigned Line,
      unsigned SizeInBits, unsigned AlignInBits, llvm::DINode::DIFlags Flags,
      StringRef MangledName) {
      // Let the MDNode folding set do the work of uniquing the inner type. This
      // should be cheap.
      llvm::DICompositeType *UniqueType = DBuilder.createStructType(
         Scope, Name, File, Line, 0, 0, Flags, nullptr,
         DBuilder.getOrCreateArray(ArrayRef<llvm::Metadata *>()),
         llvm::dwarf::DW_LANG_Swift, nullptr, MangledName);
      llvm::Metadata *Elements[] = {
         DBuilder.createMemberType(Scope, "", File, 0, SizeInBits,
                                   AlignInBits, 0, Flags, UniqueType)};

      return DBuilder.createStructType(
         Scope, "", File, Line, SizeInBits, AlignInBits, Flags,
         /* DerivedFrom */ nullptr, DBuilder.getOrCreateArray(Elements),
         llvm::dwarf::DW_LANG_Swift);
   }

   llvm::DIType *createPointerSizedStruct(llvm::DIScope *Scope, StringRef Name,
                                          llvm::DIFile *File, unsigned Line,
                                          llvm::DINode::DIFlags Flags,
                                          StringRef MangledName) {
      if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes) {
         auto FwdDecl = DBuilder.createForwardDecl(
            llvm::dwarf::DW_TAG_structure_type, Name, Scope, File, Line,
            llvm::dwarf::DW_LANG_Swift, 0, 0);
         return createPointerSizedStruct(Scope, Name, FwdDecl, File, Line, Flags,
                                         MangledName);
      } else {
         unsigned SizeInBits = CI.getTargetInfo().getPointerWidth(0);
         return createOpaqueStruct(Scope, Name, File, Line, SizeInBits, 0, Flags,
                                   MangledName);
      }
   }

   llvm::DIType *createPointerSizedStruct(llvm::DIScope *Scope, StringRef Name,
                                          llvm::DIType *PointeeTy,
                                          llvm::DIFile *File, unsigned Line,
                                          llvm::DINode::DIFlags Flags,
                                          StringRef MangledName) {
      unsigned PtrSize = CI.getTargetInfo().getPointerWidth(0);
      auto PtrTy = DBuilder.createPointerType(PointeeTy, PtrSize, 0);
      llvm::Metadata *Elements[] = {DBuilder.createMemberType(
         Scope, "ptr", File, 0, PtrSize, 0, 0, Flags, PtrTy)};
      return DBuilder.createStructType(
         Scope, Name, File, Line, PtrSize, 0, Flags,
         /* DerivedFrom */ nullptr, DBuilder.getOrCreateArray(Elements),
         llvm::dwarf::DW_LANG_Swift, nullptr, MangledName);
   }

   llvm::DIType *
   createDoublePointerSizedStruct(llvm::DIScope *Scope, StringRef Name,
                                  llvm::DIType *PointeeTy, llvm::DIFile *File,
                                  unsigned Line, llvm::DINode::DIFlags Flags,
                                  StringRef MangledName) {
      unsigned PtrSize = CI.getTargetInfo().getPointerWidth(0);
      llvm::Metadata *Elements[] = {
         DBuilder.createMemberType(
            Scope, "ptr", File, 0, PtrSize, 0, 0, Flags,
            DBuilder.createPointerType(PointeeTy, PtrSize, 0)),
         DBuilder.createMemberType(
            Scope, "_", File, 0, PtrSize, 0, 0, Flags,
            DBuilder.createPointerType(nullptr, PtrSize, 0))};
      return DBuilder.createStructType(
         Scope, Name, File, Line, 2 * PtrSize, 0, Flags,
         /* DerivedFrom */ nullptr, DBuilder.getOrCreateArray(Elements),
         llvm::dwarf::DW_LANG_Swift, nullptr, MangledName);
   }

   llvm::DIType *createFixedValueBufferStruct(llvm::DIType *PointeeTy) {
      unsigned Line = 0;
      unsigned PtrSize = CI.getTargetInfo().getPointerWidth(0);
      llvm::DINode::DIFlags Flags = llvm::DINode::FlagArtificial;
      llvm::DIFile *File = MainFile;
      llvm::DIScope *Scope = TheCU;
      llvm::Metadata *Elements[] = {DBuilder.createMemberType(
         Scope, "contents", File, 0, PtrSize, 0, 0, Flags, PointeeTy)};
      return DBuilder.createStructType(
         Scope, "$swift.fixedbuffer", File, Line, 3 * PtrSize, 0, Flags,
         /* DerivedFrom */ nullptr, DBuilder.getOrCreateArray(Elements),
         llvm::dwarf::DW_LANG_Swift, nullptr);
   }

   llvm::DIType *createFunctionPointer(DebugTypeInfo DbgTy, llvm::DIScope *Scope,
                                       unsigned SizeInBits, unsigned AlignInBits,
                                       llvm::DINode::DIFlags Flags,
                                       StringRef MangledName) {
      auto FwdDecl = llvm::TempDINode(DBuilder.createReplaceableCompositeType(
         llvm::dwarf::DW_TAG_subroutine_type, MangledName, Scope, MainFile, 0,
         llvm::dwarf::DW_LANG_Swift, SizeInBits, AlignInBits, Flags,
         MangledName));

      auto TH = llvm::TrackingMDNodeRef(FwdDecl.get());
      DITypeCache[DbgTy.getType()] = TH;

      CanPILFunctionType FunTy;
      TypeBase *BaseTy = DbgTy.getType();
      if (auto *PILFnTy = dyn_cast<PILFunctionType>(BaseTy))
         FunTy = CanPILFunctionType(PILFnTy);
         // FIXME: Handling of generic parameters in PIL type lowering is in flux.
         // DebugInfo doesn't appear to care about the generic context, so just
         // throw it away before lowering.
      else if (isa<GenericFunctionType>(BaseTy)) {
         auto *fTy = cast<AnyFunctionType>(BaseTy);
         auto *nongenericTy = FunctionType::get(fTy->getParams(), fTy->getResult(),
                                                fTy->getExtInfo());

         FunTy = IGM.getLoweredType(nongenericTy).castTo<PILFunctionType>();
      } else
         FunTy = IGM.getLoweredType(BaseTy).castTo<PILFunctionType>();
      auto Params = createParameterTypes(FunTy);

      auto FnTy = DBuilder.createSubroutineType(Params, Flags);
      llvm::DIType *DITy;
      if (FunTy->getRepresentation() == PILFunctionType::Representation::Thick) {
         if (SizeInBits == 2 * CI.getTargetInfo().getPointerWidth(0))
            // This is a FunctionPairTy: { i8*, %swift.refcounted* }.
            DITy = createDoublePointerSizedStruct(Scope, MangledName, FnTy,
                                                  MainFile, 0, Flags, MangledName);
         else
            // This is a generic function as noted above.
            DITy = createOpaqueStruct(Scope, MangledName, MainFile, 0, SizeInBits,
                                      AlignInBits, Flags, MangledName);
      } else {
         assert(SizeInBits == CI.getTargetInfo().getPointerWidth(0));
         DITy = createPointerSizedStruct(Scope, MangledName, FnTy, MainFile, 0,
                                         Flags, MangledName);
      }
      DBuilder.replaceTemporary(std::move(FwdDecl), DITy);
      return DITy;
   }

   llvm::DIType *createTuple(DebugTypeInfo DbgTy, llvm::DIScope *Scope,
                             unsigned SizeInBits, unsigned AlignInBits,
                             llvm::DINode::DIFlags Flags,
                             StringRef MangledName) {
      TypeBase *BaseTy = DbgTy.getType();
      auto *TupleTy = BaseTy->castTo<TupleType>();
      auto FwdDecl = llvm::TempDINode(DBuilder.createReplaceableCompositeType(
         llvm::dwarf::DW_TAG_structure_type, MangledName, Scope, MainFile, 0,
         llvm::dwarf::DW_LANG_Swift, SizeInBits, AlignInBits, Flags,
         MangledName));

      DITypeCache[DbgTy.getType()] = llvm::TrackingMDNodeRef(FwdDecl.get());

      unsigned RealSize;
      auto Elements = getTupleElements(TupleTy, Scope, MainFile, Flags, RealSize);
      // FIXME: Handle %swift.opaque members and make this into an assertion.
      if (!RealSize)
         RealSize = SizeInBits;

      auto DITy = DBuilder.createStructType(
         Scope, MangledName, MainFile, 0, RealSize, AlignInBits, Flags,
         nullptr, // DerivedFrom
         Elements, llvm::dwarf::DW_LANG_Swift, nullptr, MangledName);

      DBuilder.replaceTemporary(std::move(FwdDecl), DITy);
      return DITy;
   }

   llvm::DIType *createOpaqueStruct(llvm::DIScope *Scope, StringRef Name,
                                    llvm::DIFile *File, unsigned Line,
                                    unsigned SizeInBits, unsigned AlignInBits,
                                    llvm::DINode::DIFlags Flags,
                                    StringRef MangledName) {
      return DBuilder.createStructType(
         Scope, Name, File, Line, SizeInBits, AlignInBits, Flags,
         /* DerivedFrom */ nullptr,
         DBuilder.getOrCreateArray(ArrayRef<llvm::Metadata *>()),
         llvm::dwarf::DW_LANG_Swift, nullptr, MangledName);
   }

   llvm::DIType *createType(DebugTypeInfo DbgTy, StringRef MangledName,
                            llvm::DIScope *Scope, llvm::DIFile *File) {
      // FIXME: For SizeInBits, clang uses the actual size of the type on
      // the target machine instead of the storage size that is alloca'd
      // in the LLVM IR. For all types that are boxed in a struct, we are
      // emitting the storage size of the struct, but it may be necessary
      // to emit the (target!) size of the underlying basic type.
      uint64_t SizeOfByte = CI.getTargetInfo().getCharWidth();
      uint64_t SizeInBits = DbgTy.size.getValue() * SizeOfByte;
      unsigned AlignInBits =
         DbgTy.DefaultAlignment ? 0 : DbgTy.align.getValue() * SizeOfByte;
      unsigned Encoding = 0;
      llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;

      TypeBase *BaseTy = DbgTy.getType();

      if (!BaseTy) {
         LLVM_DEBUG(llvm::dbgs() << "Type without TypeBase: ";
                       DbgTy.getType()->dump(llvm::dbgs());
                       llvm::dbgs() << "\n");
         if (!InternalType) {
            StringRef Name = "<internal>";
            InternalType = DBuilder.createForwardDecl(
               llvm::dwarf::DW_TAG_structure_type, Name, Scope, File,
               /*Line*/ 0, llvm::dwarf::DW_LANG_Swift, SizeInBits, AlignInBits);
         }
         return InternalType;
      }

      // Here goes!
      switch (BaseTy->getKind()) {
         case TypeKind::BuiltinInteger: {
            Encoding = llvm::dwarf::DW_ATE_unsigned;
            SizeInBits = getSizeOfBasicType(DbgTy);
            break;
         }

         case TypeKind::BuiltinIntegerLiteral: {
            Encoding = llvm::dwarf::DW_ATE_unsigned; // ?
            SizeInBits = getSizeOfBasicType(DbgTy);
            break;
         }

         case TypeKind::BuiltinFloat: {
            auto *FloatTy = BaseTy->castTo<BuiltinFloatType>();
            // Assuming that the bitwidth and FloatTy->getFPKind() are identical.
            SizeInBits = FloatTy->getBitWidth();
            Encoding = llvm::dwarf::DW_ATE_float;
            break;
         }

         case TypeKind::BuiltinNativeObject: {
            unsigned PtrSize = CI.getTargetInfo().getPointerWidth(0);
            auto PTy =
               DBuilder.createPointerType(nullptr, PtrSize, 0,
                  /* DWARFAddressSpace */ None, MangledName);
            return DBuilder.createObjectPointerType(PTy);
         }

         case TypeKind::BuiltinBridgeObject: {
            unsigned PtrSize = CI.getTargetInfo().getPointerWidth(0);
            auto PTy =
               DBuilder.createPointerType(nullptr, PtrSize, 0,
                  /* DWARFAddressSpace */ None, MangledName);
            return DBuilder.createObjectPointerType(PTy);
         }

         case TypeKind::BuiltinRawPointer: {
            unsigned PtrSize = CI.getTargetInfo().getPointerWidth(0);
            return DBuilder.createPointerType(nullptr, PtrSize, 0,
               /* DWARFAddressSpace */ None,
                                              MangledName);
         }

         case TypeKind::DynamicSelf: {
            // Self. We don't have a way to represent instancetype in DWARF,
            // so we emit the static type instead. This is similar to what we
            // do with instancetype in Objective-C.
            auto *DynamicSelfTy = BaseTy->castTo<DynamicSelfType>();
            auto SelfTy =
               getOrCreateDesugaredType(DynamicSelfTy->getSelfType(), DbgTy);
            return DBuilder.createTypedef(SelfTy, MangledName, File, 0, File);
         }

            // Even builtin swift types usually come boxed in a struct.
         case TypeKind::Struct: {
            auto *StructTy = BaseTy->castTo<StructType>();
            auto *Decl = StructTy->getDecl();
            auto L = getDebugLoc(*this, Decl);
            auto *File = getOrCreateFile(L.Filename);
            if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
               return createStructType(DbgTy, Decl, StructTy, Scope, File, L.Line,
                                       SizeInBits, AlignInBits, Flags,
                                       nullptr, // DerivedFrom
                                       llvm::dwarf::DW_LANG_Swift, MangledName);
            else
               return createOpaqueStruct(Scope, Decl->getName().str(), File, L.Line,
                                         SizeInBits, AlignInBits, Flags, MangledName);
         }

         case TypeKind::Class: {
            // Classes are represented as DW_TAG_structure_type. This way the
            // DW_AT_APPLE_runtime_class(DW_LANG_Swift) attribute can be
            // used to differentiate them from C++ and ObjC classes.
            auto *ClassTy = BaseTy->castTo<ClassType>();
            auto *Decl = ClassTy->getDecl();
            auto L = getDebugLoc(*this, Decl);
            assert(SizeInBits == CI.getTargetInfo().getPointerWidth(0));
            return createPointerSizedStruct(Scope, Decl->getNameStr(),
                                            getOrCreateFile(L.Filename), L.Line,
                                            Flags, MangledName);
         }

         case TypeKind::Interface: {
            auto *InterfaceTy = BaseTy->castTo<InterfaceType>();
            auto *Decl = InterfaceTy->getDecl();
            // FIXME: (LLVM branch) This should probably be a DW_TAG_interface_type.
            auto L = getDebugLoc(*this, Decl);
            auto File = getOrCreateFile(L.Filename);
            return createOpaqueStruct(Scope, Decl ? Decl->getNameStr() : MangledName,
                                      File, L.Line, SizeInBits, AlignInBits, Flags,
                                      MangledName);
         }

         case TypeKind::InterfaceComposition: {
            auto *Decl = DbgTy.getDecl();
            auto L = getDebugLoc(*this, Decl);
            auto File = getOrCreateFile(L.Filename);

            // FIXME: emit types
            // auto InterfaceCompositionTy = BaseTy->castTo<InterfaceCompositionType>();
            return createOpaqueStruct(Scope, Decl ? Decl->getNameStr() : MangledName,
                                      File, L.Line, SizeInBits, AlignInBits, Flags,
                                      MangledName);
         }

         case TypeKind::UnboundGeneric: {
            auto *UnboundTy = BaseTy->castTo<UnboundGenericType>();
            auto *Decl = UnboundTy->getDecl();
            auto L = getDebugLoc(*this, Decl);
            assert(SizeInBits == CI.getTargetInfo().getPointerWidth(0));
            return createPointerSizedStruct(Scope,
                                            Decl ? Decl->getNameStr() : MangledName,
                                            File, L.Line, Flags, MangledName);
         }

         case TypeKind::BoundGenericStruct: {
            auto *StructTy = BaseTy->castTo<BoundGenericStructType>();
            auto *Decl = StructTy->getDecl();
            auto L = getDebugLoc(*this, Decl);
            return createOpaqueStructWithSizedContainer(
               Scope, Decl ? Decl->getNameStr() : "", File, L.Line, SizeInBits,
               AlignInBits, Flags, MangledName);
         }

         case TypeKind::BoundGenericClass: {
            auto *ClassTy = BaseTy->castTo<BoundGenericClassType>();
            auto *Decl = ClassTy->getDecl();
            auto L = getDebugLoc(*this, Decl);
            // TODO: We may want to peek at Decl->isObjC() and set this
            // attribute accordingly.
            assert(SizeInBits == CI.getTargetInfo().getPointerWidth(0));
            return createPointerSizedStruct(Scope,
                                            Decl ? Decl->getNameStr() : MangledName,
                                            File, L.Line, Flags, MangledName);
         }

         case TypeKind::Tuple: {
            // Tuples are also represented as structs.
            if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
               return createTuple(DbgTy, Scope, SizeInBits, AlignInBits, Flags,
                                  MangledName);
            else
               return createOpaqueStruct(Scope, MangledName, MainFile, 0, SizeInBits,
                                         AlignInBits, Flags, MangledName);
         }

         case TypeKind::InOut:
            break;

         case TypeKind::OpaqueTypeArchetype:
         case TypeKind::PrimaryArchetype:
         case TypeKind::OpenedArchetype:
         case TypeKind::NestedArchetype: {
            auto *Archetype = BaseTy->castTo<ArchetypeType>();
            AssociatedTypeDecl *assocType = nullptr;
            if (auto nested = dyn_cast<NestedArchetypeType>(Archetype))
               assocType = nested->getAssocType();
            auto L = getDebugLoc(*this, assocType);
            auto Superclass = Archetype->getSuperclass();
            auto DerivedFrom = Superclass.isNull()
                               ? nullptr
                               : getOrCreateDesugaredType(Superclass, DbgTy);
            auto FwdDecl = llvm::TempDIType(DBuilder.createReplaceableCompositeType(
               llvm::dwarf::DW_TAG_structure_type, MangledName, Scope, File, L.Line,
               llvm::dwarf::DW_LANG_Swift, SizeInBits, AlignInBits, Flags,
               MangledName));

            // Emit the protocols the archetypes conform to.
            SmallVector<llvm::Metadata *, 4> Interfaces;
            for (auto *InterfaceDecl : Archetype->getConformsTo()) {
               auto PTy = IGM.getLoweredType(InterfaceDecl->getInterfaceType())
                  .getAstType();
               auto PDbgTy = DebugTypeInfo::getFromTypeInfo(
                  InterfaceDecl->getInterfaceType(), IGM.getTypeInfoForLowered(PTy));
               auto PDITy = getOrCreateType(PDbgTy);
               Interfaces.push_back(
                  DBuilder.createInheritance(FwdDecl.get(), PDITy, 0, 0, Flags));
            }
            auto DITy = DBuilder.createStructType(
               Scope, MangledName, File, L.Line, SizeInBits, AlignInBits, Flags,
               DerivedFrom, DBuilder.getOrCreateArray(Interfaces),
               llvm::dwarf::DW_LANG_Swift, nullptr, MangledName);

            DBuilder.replaceTemporary(std::move(FwdDecl), DITy);
            return DITy;
         }

         case TypeKind::ExistentialMetatype:
         case TypeKind::Metatype: {
            // Metatypes are (mostly) singleton type descriptors, often without
            // storage.
            Flags |= llvm::DINode::FlagArtificial;
            auto L = getDebugLoc(*this, DbgTy.getDecl());
            auto File = getOrCreateFile(L.Filename);
            return DBuilder.createStructType(
               Scope, MangledName, File, L.Line, SizeInBits, AlignInBits, Flags,
               nullptr, nullptr, llvm::dwarf::DW_LANG_Swift, nullptr, MangledName);
         }

         case TypeKind::PILFunction:
         case TypeKind::Function:
         case TypeKind::GenericFunction: {
            if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
               return createFunctionPointer(DbgTy, Scope, SizeInBits, AlignInBits,
                                            Flags, MangledName);
            else
               return createOpaqueStruct(Scope, MangledName, MainFile, 0, SizeInBits,
                                         AlignInBits, Flags, MangledName);
         }

         case TypeKind::Enum: {
            auto *EnumTy = BaseTy->castTo<EnumType>();
            auto *Decl = EnumTy->getDecl();
            auto L = getDebugLoc(*this, Decl);
            auto *File = getOrCreateFile(L.Filename);
            if (Opts.DebugInfoLevel > IRGenDebugInfoLevel::ASTTypes)
               return createEnumType(DbgTy, Decl, MangledName, Scope, File, L.Line,
                                     Flags);
            else
               return createOpaqueStruct(Scope, Decl->getName().str(), File, L.Line,
                                         SizeInBits, AlignInBits, Flags, MangledName);
         }

         case TypeKind::BoundGenericEnum: {
            auto *EnumTy = BaseTy->castTo<BoundGenericEnumType>();
            auto *Decl = EnumTy->getDecl();
            auto L = getDebugLoc(*this, Decl);
            auto *File = getOrCreateFile(L.Filename);
            return createOpaqueStructWithSizedContainer(
               Scope, Decl->getName().str(), File, L.Line, SizeInBits, AlignInBits,
               Flags, MangledName);
         }

         case TypeKind::BuiltinVector: {
            (void)MangledName; // FIXME emit the name somewhere.
            auto *BuiltinVectorTy = BaseTy->castTo<BuiltinVectorType>();
            auto ElemTy = BuiltinVectorTy->getElementType();
            auto ElemDbgTy = DebugTypeInfo::getFromTypeInfo(
               ElemTy, IGM.getTypeInfoForUnlowered(ElemTy));
            unsigned Count = BuiltinVectorTy->getNumElements();
            auto Subscript = DBuilder.getOrCreateSubrange(0, Count ? Count : -1);
            return DBuilder.createVectorType(SizeInBits,
                                             AlignInBits, getOrCreateType(ElemDbgTy),
                                             DBuilder.getOrCreateArray(Subscript));
         }

            // Reference storage types.
#define REF_STORAGE(Name, ...) \
    case TypeKind::Name##Storage:
#include "polarphp/ast/ReferenceStorageDef.h"
            {
               auto *ReferenceTy = cast<ReferenceStorageType>(BaseTy);
               auto CanTy = ReferenceTy->getReferentType();
               auto L = getDebugLoc(*this, DbgTy.getDecl());
               auto File = getOrCreateFile(L.Filename);
               return DBuilder.createTypedef(getOrCreateDesugaredType(CanTy, DbgTy),
                                             MangledName, File, L.Line, File);
            }

            // Sugared types.

         case TypeKind::TypeAlias: {
            auto *TypeAliasTy = cast<TypeAliasType>(BaseTy);
            auto *Decl = TypeAliasTy->getDecl();
            auto L = getDebugLoc(*this, Decl);
            auto AliasedTy = TypeAliasTy->getSinglyDesugaredType();
            auto File = getOrCreateFile(L.Filename);
            // For TypeAlias types, the DeclContext for the aliased type is
            // in the decl of the alias type.
            DebugTypeInfo AliasedDbgTy(AliasedTy, DbgTy.StorageType, DbgTy.size,
                                       DbgTy.align, DbgTy.DefaultAlignment,
                                       false);
            return DBuilder.createTypedef(getOrCreateType(AliasedDbgTy), MangledName,
                                          File, L.Line, Scope);
         }

         case TypeKind::Paren: {
            auto Ty = cast<ParenType>(BaseTy)->getUnderlyingType();
            return getOrCreateDesugaredType(Ty, DbgTy);
         }

            // SyntaxSugarType derivations.
         case TypeKind::Dictionary:
         case TypeKind::ArraySlice:
         case TypeKind::Optional: {
            auto *SyntaxSugarTy = cast<SyntaxSugarType>(BaseTy);
            auto *CanTy = SyntaxSugarTy->getSinglyDesugaredType();
            return getOrCreateDesugaredType(CanTy, DbgTy);
         }

         case TypeKind::DependentMember:
         case TypeKind::GenericTypeParam: {
            // FIXME: Provide a more meaningful debug type.
            return DBuilder.createStructType(
               Scope, MangledName, File, 0, SizeInBits, AlignInBits, Flags,
               nullptr, nullptr,
               llvm::dwarf::DW_LANG_Swift, nullptr, MangledName);
         }

            // The following types exist primarily for internal use by the type
            // checker.
         case TypeKind::Error:
         case TypeKind::Unresolved:
         case TypeKind::LValue:
         case TypeKind::TypeVariable:
         case TypeKind::Module:
         case TypeKind::PILBlockStorage:
         case TypeKind::PILBox:
         case TypeKind::PILToken:
         case TypeKind::BuiltinUnsafeValueBuffer:

            LLVM_DEBUG(llvm::dbgs() << "Unhandled type: ";
                          DbgTy.getType()->dump(llvm::dbgs());
                          llvm::dbgs() << "\n");
            MangledName = "<unknown>";
      }
      return DBuilder.createBasicType(MangledName, SizeInBits, Encoding);
   }

   /// Determine if there exists a name mangling for the given type.
   static bool canMangle(TypeBase *Ty) {
      switch (Ty->getKind()) {
         case TypeKind::GenericFunction: // Not yet supported.
         case TypeKind::PILBlockStorage: // Not supported at all.
         case TypeKind::PILBox:
            return false;
         default:
            return true;
      }
   }

   llvm::DIType *getTypeOrNull(TypeBase *Ty) {
      auto CachedType = DITypeCache.find(Ty);
      if (CachedType != DITypeCache.end()) {
         // Verify that the information still exists.
         if (llvm::Metadata *Val = CachedType->second) {
            auto DITy = cast<llvm::DIType>(Val);
            return DITy;
         }
      }
      return nullptr;
   }

   /// The private discriminator is represented as an inline namespace.
   llvm::DIScope *getFilePrivateScope(llvm::DIScope *Parent, TypeDecl *Decl) {
      // Retrieve the private discriminator.
      auto *MSC = Decl->getDeclContext()->getModuleScopeContext();
      auto *FU = cast<FileUnit>(MSC);
      Identifier PD = FU->getDiscriminatorForPrivateValue(Decl);
      bool ExportSymbols = true;
      return DBuilder.createNameSpace(Parent, PD.str(), ExportSymbols);
   }

   llvm::DIType *getOrCreateType(DebugTypeInfo DbgTy) {
      // Is this an empty type?
      if (DbgTy.isNull())
         // We can't use the empty type as an index into DenseMap.
         return createType(DbgTy, "", TheCU, MainFile);

      // Look in the cache first.
      if (auto *DITy = getTypeOrNull(DbgTy.getType()))
         return DITy;

      // Second line of defense: Look up the mangled name. TypeBase*'s are
      // not necessarily unique, but name mangling is too expensive to do
      // every time.
      StringRef MangledName;
      llvm::MDString *UID = nullptr;
      if (canMangle(DbgTy.getType())) {
         MangledName = getMangledName(DbgTy);
         UID = llvm::MDString::get(IGM.getLLVMContext(), MangledName);
         if (llvm::Metadata *CachedTy = DIRefMap.lookup(UID)) {
            auto DITy = cast<llvm::DIType>(CachedTy);
            return DITy;
         }
      }

      // Retrieve the context of the type, as opposed to the DeclContext
      // of the variable.
      //
      // FIXME: Builtin and qualified types in LLVM have no parent
      // scope. TODO: This can be fixed by extending DIBuilder.
      llvm::DIScope *Scope = nullptr;
      // Make sure to retrieve the context of the type alias, not the pointee.
      DeclContext *Context = nullptr;
      const Decl *TypeDecl = nullptr;
      const clang::Decl *ClangDecl = nullptr;
      if (auto Alias = dyn_cast<TypeAliasType>(DbgTy.getType())) {
         TypeAliasDecl *AliasDecl = Alias->getDecl();
         TypeDecl = AliasDecl;
         Context = AliasDecl->getParent();
         ClangDecl = AliasDecl->getClangDecl();
      } else if (auto *ND = DbgTy.getType()->getNominalOrBoundGenericNominal()) {
         TypeDecl = ND;
         Context = ND->getParent();
         ClangDecl = ND->getClangDecl();
      }
      if (ClangDecl) {
         clang::ASTReader &Reader = *CI.getClangInstance().getASTReader();
         auto Idx = ClangDecl->getOwningModuleID();
         auto SubModuleDesc = Reader.getSourceDescriptor(Idx);
         auto TopLevelModuleDesc = getClangModule(*TypeDecl->getModuleContext());
         if (SubModuleDesc) {
            if (TopLevelModuleDesc)
               // Describe the submodule, but substitute the cached ASTFile from
               // the toplevel module. The ASTFile pointer in SubModule may be
               // dangling and cant be trusted.
               Scope = getOrCreateModule({SubModuleDesc->getModuleName(),
                                          SubModuleDesc->getPath(),
                                          TopLevelModuleDesc->getASTFile(),
                                          TopLevelModuleDesc->getSignature()},
                                         SubModuleDesc->getModuleOrNull());
            else if (SubModuleDesc->getModuleOrNull() == nullptr)
               // This is (bridging header) PCH.
               Scope = getOrCreateModule(*SubModuleDesc, nullptr);
         }
      }
      if (!Scope)
         Scope = getOrCreateContext(Context);

      // Scope outermost fileprivate decls in an inline private discriminator
      // namespace.
      if (auto *Decl = DbgTy.getDecl())
         if (Decl->isOutermostPrivateOrFilePrivateScope())
            Scope = getFilePrivateScope(Scope, Decl);

      llvm::DIType *DITy = createType(DbgTy, MangledName, Scope, getFile(Scope));

      // Incrementally build the DIRefMap.
      if (auto *CTy = dyn_cast<llvm::DICompositeType>(DITy)) {
#ifndef NDEBUG
         // Sanity check.
         if (llvm::Metadata *V = DIRefMap.lookup(UID)) {
            auto *CachedTy = cast<llvm::DIType>(V);
            assert(CachedTy == DITy && "conflicting types for one UID");
         }
#endif
         // If this type supports a UID, enter it to the cache.
         if (auto UID = CTy->getRawIdentifier()) {
            assert(UID->getString() == MangledName &&
                   "Unique identifier is different from mangled name ");
            DIRefMap[UID] = llvm::TrackingMDNodeRef(DITy);
         }
      }

      // Store it in the cache.
      DITypeCache.insert({DbgTy.getType(), llvm::TrackingMDNodeRef(DITy)});

      return DITy;
   }
};

IRGenDebugInfoImpl::IRGenDebugInfoImpl(const IRGenOptions &Opts,
                                       ClangImporter &CI, IRGenModule &IGM,
                                       llvm::Module &M,
                                       StringRef MainOutputFilenameForDebugInfo)
   : Opts(Opts), CI(CI), SM(IGM.Context.SourceMgr), M(M), DBuilder(M),
     IGM(IGM), DebugPrefixMap(Opts.DebugPrefixMap) {
   assert(Opts.DebugInfoLevel > IRGenDebugInfoLevel::None &&
          "no debug info should be generated");
   llvm::SmallString<256> SourcePath;
   if (MainOutputFilenameForDebugInfo.empty())
      SourcePath = "<unknown>";
   else
      SourcePath = MainOutputFilenameForDebugInfo;

   unsigned Lang = llvm::dwarf::DW_LANG_Swift;
   std::string Producer = version::retrieve_polarphp_full_version(
      IGM.Context.LangOpts.EffectiveLanguageVersion);
   StringRef Flags = Opts.DebugFlags;
   unsigned Major, Minor;
   std::tie(Major, Minor) = version::retrieve_polarphp_numeric_version();
   unsigned MajorRuntimeVersion = Major;

   // No split DWARF on Darwin.
   StringRef SplitName = StringRef();
   // Note that File + Dir need not result in a valid path.
   // The directory part of the main file is the current working directory.
   MainFile =
      DBuilder.createFile(DebugPrefixMap.remapPath(SourcePath),
                          DebugPrefixMap.remapPath(Opts.DebugCompilationDir));

   TheCU = DBuilder.createCompileUnit(
      Lang, MainFile,
      Producer, Opts.shouldOptimize(), Flags, MajorRuntimeVersion, SplitName,
      Opts.DebugInfoLevel > IRGenDebugInfoLevel::LineTables
      ? llvm::DICompileUnit::FullDebug
      : llvm::DICompileUnit::LineTablesOnly);

   // Because the swift compiler relies on Clang to setup the Module,
   // the clang CU is always created first.  Several dwarf-reading
   // tools (older versions of ld64, and lldb) can get confused if the
   // first CU in an object is empty, so ensure that the Swift CU comes
   // first by rearranging the list of CUs in the LLVM module.
   llvm::NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu");
   SmallVector<llvm::DICompileUnit *, 2> CUs;
   for (auto *N : CU_Nodes->operands())
      CUs.push_back(cast<llvm::DICompileUnit>(N));
   CU_Nodes->dropAllReferences();
   for (auto CU = CUs.rbegin(), CE = CUs.rend(); CU != CE; ++CU)
      CU_Nodes->addOperand(*CU);

   // Create a module for the current compile unit.
   auto *MDecl = IGM.getPolarphpModule();
   llvm::sys::path::remove_filename(SourcePath);
   MainModule = getOrCreateModule(MDecl, TheCU, Opts.ModuleName, SourcePath);
   DBuilder.createImportedModule(MainFile, MainModule, MainFile, 0);

   // Macro definitions that were defined by the user with "-Xcc -D" on the
   // command line. This does not include any macros defined by ClangImporter.
   llvm::raw_svector_ostream OS(ConfigMacros);
   unsigned I = 0;
   // Translate the macro definitions back into a commmand line.
   for (auto &Macro : Opts.ClangDefines) {
      if (++I > 1)
         OS << ' ';
      OS << '"';
      for (char c : Macro)
         switch (c) {
            case '\\': OS << "\\\\"; break;
            case '"':  OS << "\\\""; break;
            default: OS << c;
         }
      OS << '"';
   }
}

void IRGenDebugInfoImpl::finalize() {
   assert(LocationStack.empty() && "Mismatch of pushLoc() and popLoc().");

   // Get the list of imported modules (which may actually be different
   // from all ImportDecls).
   ModuleDecl::ImportFilter ImportFilter;
   ImportFilter |= ModuleDecl::ImportFilterKind::Public;
   ImportFilter |= ModuleDecl::ImportFilterKind::Private;
   ImportFilter |= ModuleDecl::ImportFilterKind::ImplementationOnly;
   SmallVector<ModuleDecl::ImportedModule, 8> ModuleWideImports;
   IGM.getPolarphpModule()->getImportedModules(ModuleWideImports, ImportFilter);
   for (auto M : ModuleWideImports)
      if (!ImportedModules.count(M.second))
         DBuilder.createImportedModule(MainFile, getOrCreateModule(M), MainFile,
                                       0);

   // Finalize all replaceable forward declarations.
   for (auto &Ty : ReplaceMap) {
      llvm::TempMDNode FwdDecl(cast<llvm::MDNode>(Ty.second));
      llvm::Metadata *Replacement;
      if (auto *FullType = getTypeOrNull(Ty.first))
         Replacement = FullType;
      else
         Replacement = Ty.second;
      DBuilder.replaceTemporary(std::move(FwdDecl),
                                cast<llvm::MDNode>(Replacement));
   }
   // Finalize the DIBuilder.
   DBuilder.finalize();
}

#ifndef NDEBUG
bool IRGenDebugInfoImpl::lineEntryIsSane(PILLocation::DebugLoc DL,
                                         const PILDebugScope *DS) {
   // All bets are off for optimized code.
   if (!VerifyLineTable || Opts.shouldOptimize())
      return true;
   // We entered a new lexical block.
   if (DS != LastScope)
      PreviousLineEntries.clear();
   if (DL.Line == 0 || DL == PreviousDebugLoc)
      return true;
   // Save the last non-zero line entry.
   PreviousDebugLoc = DL;
   auto ItNew = PreviousLineEntries.insert(DebugLocKey(DL));
   // Return true iff DL was not yet in PreviousLineEntries.
   return ItNew.second;
}
#endif

void IRGenDebugInfoImpl::setCurrentLoc(IRBuilder &Builder,
                                       const PILDebugScope *DS,
                                       PILLocation Loc) {
   assert(DS && "empty scope");
   auto *Scope = getOrCreateScope(DS);
   if (!Scope)
      return;

   // NOTE: In CodeView, zero is not an artificial line location. We try to
   //       avoid those line locations near user code to reduce the number
   //       of breaks in the linetables.
   PILLocation::DebugLoc L;
   PILFunction *Fn = DS->getInlinedFunction();
   if (Fn && (Fn->isThunk() || Fn->isTransparent())) {
      L = PILLocation::getCompilerGeneratedDebugLoc();
   } else if (DS == LastScope && Loc.isAutoGenerated()) {
      // Reuse the last source location if we are still in the same
      // scope to get a more contiguous line table.
      L = LastDebugLoc;
   } else if (DS == LastScope &&
              (Loc.is<ArtificialUnreachableLocation>() || Loc.isLineZero(SM)) &&
              Opts.DebugInfoFormat == IRGenDebugInfoFormat::CodeView) {
      // If the scope has not changed and the line number is either zero or
      // artificial, we want to keep the most recent debug location.
      L = LastDebugLoc;
   } else {
      // Decode the location.
      L = getDebugLocation(Loc);
      // Otherwise use a line 0 artificial location, but the file from the
      // location. If we are emitting CodeView, we do not want to use line zero
      // since it does not represent an artificial line location.
      if (Loc.isAutoGenerated() &&
          Opts.DebugInfoFormat != IRGenDebugInfoFormat::CodeView) {
         L.Line = 0;
         L.Column = 0;
      }
   }

   auto *File = getOrCreateFile(L.Filename);
   if (File->getFilename() != Scope->getFilename()) {
      // We changed files in the middle of a scope. This happens, for
      // example, when constructors are inlined. Create a new scope to
      // reflect this.
      auto File = getOrCreateFile(L.Filename);
      Scope = DBuilder.createLexicalBlockFile(Scope, File);
   }

   // FIXME: Enable this assertion.
   assert(lineEntryIsSane(L, DS) &&
          "non-contiguous debug location in same scope at -Onone");
   LastDebugLoc = L;
   LastScope = DS;

   auto *InlinedAt = createInlinedAt(DS);
   assert(((!InlinedAt) || (InlinedAt && Scope)) && "inlined w/o scope");
   assert(parentScopesAreSane(DS) && "parent scope sanity check failed");
   auto DL = llvm::DebugLoc::get(L.Line, L.Column, Scope, InlinedAt);
   Builder.SetCurrentDebugLocation(DL);
}

void IRGenDebugInfoImpl::addFailureMessageToCurrentLoc(IRBuilder &Builder,
                                                       StringRef failureMsg) {
   auto TrapLoc = Builder.getCurrentDebugLocation();

   // Create a function in the debug info which has failureMsg as name.
   // TrapSc is the PIL debug scope which corresponds to TrapSP in the LLVM debug
   // info.
   RegularLocation ALoc = RegularLocation::getAutoGeneratedLocation();
   const PILDebugScope *TrapSc = new (IGM.getPILModule()) PILDebugScope(ALoc);

   llvm::DISubroutineType *DIFnTy = DBuilder.createSubroutineType(nullptr);

   std::string FuncName = "Swift runtime failure: ";
   FuncName += failureMsg;

   llvm::DISubprogram *TrapSP = DBuilder.createFunction(
      MainModule, StringRef(), FuncName, TrapLoc->getFile(), 0, DIFnTy, 0,
      llvm::DINode::FlagArtificial, llvm::DISubprogram::SPFlagDefinition,
      nullptr, nullptr, nullptr);

   ScopeCache[TrapSc] = llvm::TrackingMDNodeRef(TrapSP);
   LastScope = TrapSc;

   assert(parentScopesAreSane(TrapSc) && "parent scope sanity check failed");

   // Wrap the existing TrapLoc into the failure function.
   auto DL = llvm::DebugLoc::get(0, 0, TrapSP, TrapLoc);
   Builder.SetCurrentDebugLocation(DL);
}

void IRGenDebugInfoImpl::clearLoc(IRBuilder &Builder) {
   LastDebugLoc = {};
   LastScope = nullptr;
   Builder.SetCurrentDebugLocation(llvm::DebugLoc());
}

/// Push the current debug location onto a stack and initialize the
/// IRBuilder to an empty location.
void IRGenDebugInfoImpl::pushLoc() {
   LocationStack.push_back(std::make_pair(LastDebugLoc, LastScope));
   LastDebugLoc = {};
   LastScope = nullptr;
}

/// Restore the current debug location from the stack.
void IRGenDebugInfoImpl::popLoc() {
   std::tie(LastDebugLoc, LastScope) = LocationStack.pop_back_val();
}

/// This is done for WinDbg to avoid having two non-contiguous sets of
/// instructions because the ``@llvm.trap`` instruction gets placed at the end
/// of the function.
void IRGenDebugInfoImpl::setInlinedTrapLocation(IRBuilder &Builder,
                                                const PILDebugScope *Scope) {
   if (Opts.DebugInfoFormat != IRGenDebugInfoFormat::CodeView)
      return;

   // The @llvm.trap could be inlined into a chunk of code that was also inlined.
   // If this is the case then simply using the LastScope's location would
   // generate debug info that claimed Function A owned Block X and Block X
   // thought it was owned by Function B. Therefore, we need to find the last
   // inlined scope to point to.
   const PILDebugScope *TheLastScope = LastScope;
   while (TheLastScope->InlinedCallSite &&
          TheLastScope->InlinedCallSite != TheLastScope) {
      TheLastScope = TheLastScope->InlinedCallSite;
   }
   auto LastLocation = llvm::DebugLoc::get(
      LastDebugLoc.Line, LastDebugLoc.Column, getOrCreateScope(TheLastScope));
   // FIXME: This location should point to stdlib instead of being artificial.
   auto DL = llvm::DebugLoc::get(0, 0, getOrCreateScope(Scope), LastLocation);
   Builder.SetCurrentDebugLocation(DL);
}

void IRGenDebugInfoImpl::setEntryPointLoc(IRBuilder &Builder) {
   auto DL = llvm::DebugLoc::get(0, 0, getEntryPointFn(), nullptr);
   Builder.SetCurrentDebugLocation(DL);
}

llvm::DIScope *IRGenDebugInfoImpl::getEntryPointFn() {
   // Lazily create EntryPointFn.
   if (!EntryPointFn) {
      EntryPointFn = DBuilder.createReplaceableCompositeType(
         llvm::dwarf::DW_TAG_subroutine_type, POLAR_ENTRY_POINT_FUNCTION,
         MainFile, MainFile, 0);
   }
   return EntryPointFn;
}

llvm::DIScope *IRGenDebugInfoImpl::getOrCreateScope(const PILDebugScope *DS) {
   if (DS == nullptr)
      return MainFile;

   // Try to find it in the cache first.
   auto CachedScope = ScopeCache.find(DS);
   if (CachedScope != ScopeCache.end())
      return cast<llvm::DIScope>(CachedScope->second);

   // If this is an (inlined) function scope, the function may
   // not have been created yet.
   if (auto *PILFn = DS->Parent.dyn_cast<PILFunction *>()) {
      auto *FnScope = PILFn->getDebugScope();
      // FIXME: This is a bug in the PIL deserialization.
      if (!FnScope)
         PILFn->setDebugScope(DS);

      auto CachedScope = ScopeCache.find(FnScope);
      if (CachedScope != ScopeCache.end())
         return cast<llvm::DIScope>(CachedScope->second);

      // Force the debug info for the function to be emitted, even if it
      // is external or has been inlined.
      llvm::Function *Fn = nullptr;
      if (!PILFn->getName().empty() && !PILFn->isZombie())
         Fn = IGM.getAddrOfPILFunction(PILFn, NotForDefinition);
      auto *SP = emitFunction(*PILFn, Fn);

      // Cache it.
      ScopeCache[DS] = llvm::TrackingMDNodeRef(SP);
      return SP;
   }

   auto *ParentScope = DS->Parent.get<const PILDebugScope *>();
   llvm::DIScope *Parent = getOrCreateScope(ParentScope);
   assert(isa<llvm::DILocalScope>(Parent) && "not a local scope");

   if (Opts.DebugInfoLevel <= IRGenDebugInfoLevel::LineTables)
      return Parent;

   assert(DS->Parent && "lexical block must have a parent subprogram");
   auto L = getStartLocation(DS->Loc);
   llvm::DIFile *File = getOrCreateFile(L.Filename);
   auto *DScope = DBuilder.createLexicalBlock(Parent, File, L.Line, L.Column);

   // Cache it.
   ScopeCache[DS] = llvm::TrackingMDNodeRef(DScope);
   return DScope;
}

void IRGenDebugInfoImpl::emitImport(ImportDecl *D) {
   if (Opts.DebugInfoLevel <= IRGenDebugInfoLevel::LineTables)
      return;

   assert(D->getModule() && "compiler-synthesized ImportDecl is incomplete");
   ModuleDecl::ImportedModule Imported = {D->getModulePath(), D->getModule()};
   auto DIMod = getOrCreateModule(Imported);
   auto L = getDebugLoc(*this, D);
   auto *File = getOrCreateFile(L.Filename);
   DBuilder.createImportedModule(File, DIMod, File, L.Line);
   ImportedModules.insert(Imported.second);
}

llvm::DISubprogram *IRGenDebugInfoImpl::emitFunction(PILFunction &PILFn,
                                                     llvm::Function *Fn) {
   auto *DS = PILFn.getDebugScope();
   assert(DS && "PIL function has no debug scope");
   (void)DS;
   return emitFunction(PILFn.getDebugScope(), Fn, PILFn.getRepresentation(),
                       PILFn.getLoweredType(), PILFn.getDeclContext());
}

llvm::DISubprogram *
IRGenDebugInfoImpl::emitFunction(const PILDebugScope *DS, llvm::Function *Fn,
                                 PILFunctionTypeRepresentation Rep,
                                 PILType PILTy, DeclContext *DeclCtx) {
   auto Cached = ScopeCache.find(DS);
   if (Cached != ScopeCache.end()) {
      auto SP = cast<llvm::DISubprogram>(Cached->second);
      // If we created the DISubprogram for a forward declaration,
      // attach it to the function now.
      if (!Fn->getSubprogram() && !Fn->isDeclaration())
         Fn->setSubprogram(SP);
      return SP;
   }

   // Some IRGen-generated helper functions don't have a corresponding
   // PIL function, hence the dyn_cast.
   auto *PILFn = DS ? DS->Parent.dyn_cast<PILFunction *>() : nullptr;

   StringRef LinkageName;
   if (Fn)
      LinkageName = Fn->getName();
   else if (DS)
      LinkageName = PILFn->getName();
   else
      llvm_unreachable("function has no mangled name");

   StringRef Name;
   if (DS) {
      if (DS->Loc.isPILFile())
         Name = PILFn->getName();
      else
         Name = getName(DS->Loc);
   }

   /// The source line used for the function prologue.
   unsigned ScopeLine = 0;
   PILLocation::DebugLoc L;
   if (!DS || (PILFn && (PILFn->isBare() || PILFn->isThunk() ||
                         PILFn->isTransparent()))) {
      // Bare functions and thunks should not have any line numbers. This
      // is especially important for shared functions like reabstraction
      // thunk helpers, where DS->Loc is an arbitrary location of whichever use
      // was emitted first.
      L = PILLocation::getCompilerGeneratedDebugLoc();
   } else {
      L = decodeDebugLoc(DS->Loc);
      ScopeLine = L.Line;
      if (!DS->Loc.isDebugInfoLoc())
         L = decodeSourceLoc(DS->Loc.getSourceLoc());
   }

   auto Line = L.Line;
   auto File = getOrCreateFile(L.Filename);
   llvm::DIScope *Scope = MainModule;
   if (PILFn && PILFn->getDeclContext())
      Scope = getOrCreateContext(PILFn->getDeclContext()->getParent());

   // We know that main always comes from MainFile.
   if (LinkageName == POLAR_ENTRY_POINT_FUNCTION) {
      File = MainFile;
      Line = 1;
      Name = LinkageName;
   }

   CanPILFunctionType FnTy = getFunctionType(PILTy);
   auto Params = Opts.DebugInfoLevel > IRGenDebugInfoLevel::LineTables
                 ? createParameterTypes(PILTy)
                 : nullptr;
   llvm::DISubroutineType *DIFnTy = DBuilder.createSubroutineType(Params);
   llvm::DITemplateParameterArray TemplateParameters = nullptr;
   llvm::DISubprogram *Decl = nullptr;

   // Various flags.
   llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
   // Mark everything that is not visible from the source code (i.e.,
   // does not have a Swift name) as artificial, so the debugger can
   // ignore it. Explicit closures are exempt from this rule. We also
   // make an exception for toplevel code, which, although it does not
   // have a Swift name, does appear prominently in the source code.
   // ObjC thunks should also not show up in the linetable, because we
   // never want to set a breakpoint there.
   if ((Name.empty() && LinkageName != POLAR_ENTRY_POINT_FUNCTION &&
        !isExplicitClosure(PILFn)) ||
       (Rep == PILFunctionTypeRepresentation::ObjCMethod) ||
       isAllocatingConstructor(Rep, DeclCtx)) {
      Flags |= llvm::DINode::FlagArtificial;
      ScopeLine = 0;
   }

   if (FnTy &&
       FnTy->getRepresentation() == PILFunctionType::Representation::Block)
      Flags |= llvm::DINode::FlagAppleBlock;

   // Get the throws information.
   llvm::DITypeArray Error = nullptr;
   if (FnTy)
      if (auto ErrorInfo = FnTy->getOptionalErrorResult()) {
         auto DTI = DebugTypeInfo::getFromTypeInfo(
            ErrorInfo->getReturnValueType(IGM.getPILModule(), FnTy),
            IGM.getTypeInfo(IGM.silConv.getPILType(*ErrorInfo, FnTy)));
         Error = DBuilder.getOrCreateArray({getOrCreateType(DTI)}).get();
      }

   llvm::DISubprogram::DISPFlags SPFlags = llvm::DISubprogram::toSPFlags(
      /*IsLocalToUnit=*/Fn ? Fn->hasInternalLinkage() : true,
      /*IsDefinition=*/true, /*IsOptimized=*/Opts.shouldOptimize());

   // Construct the DISubprogram.
   llvm::DISubprogram *SP = DBuilder.createFunction(
      Scope, Name, LinkageName, File, Line, DIFnTy, ScopeLine, Flags, SPFlags,
      TemplateParameters, Decl, Error);

   if (Fn && !Fn->isDeclaration())
      Fn->setSubprogram(SP);

   // RAUW the entry point function forward declaration with the real thing.
   if (LinkageName == POLAR_ENTRY_POINT_FUNCTION) {
      if (EntryPointFn) {
         assert(EntryPointFn->isTemporary() &&
                "more than one entry point function");
         EntryPointFn->replaceAllUsesWith(SP);
         llvm::MDNode::deleteTemporary(EntryPointFn);
      }
      EntryPointFn = SP;
   }

   if (!DS)
      return nullptr;

   ScopeCache[DS] = llvm::TrackingMDNodeRef(SP);
   return SP;
}

void IRGenDebugInfoImpl::emitArtificialFunction(IRBuilder &Builder,
                                                llvm::Function *Fn,
                                                PILType PILTy) {
   RegularLocation ALoc = RegularLocation::getAutoGeneratedLocation();
   const PILDebugScope *Scope = new (IGM.getPILModule()) PILDebugScope(ALoc);
   emitFunction(Scope, Fn, PILFunctionTypeRepresentation::Thin, PILTy);
   /// Reusing the current file would be wrong: An objc thunk, for example, could
   /// be triggered from any random location. Use a placeholder name instead.
   setCurrentLoc(Builder, Scope, ALoc);
}

void IRGenDebugInfoImpl::emitVariableDeclaration(
   IRBuilder &Builder, ArrayRef<llvm::Value *> Storage, DebugTypeInfo DbgTy,
   const PILDebugScope *DS, ValueDecl *VarDecl, PILDebugVariable VarInfo,
   IndirectionKind Indirection, ArtificialKind Artificial) {
   assert(DS && "variable has no scope");

   if (Opts.DebugInfoLevel <= IRGenDebugInfoLevel::LineTables)
      return;

   // We cannot yet represent opened existentials.
   if (DbgTy.Type->hasOpenedExistential())
      return;

   if (!DbgTy.size)
      DbgTy.size = getStorageSize(IGM.DataLayout, Storage);

   auto *Scope = dyn_cast_or_null<llvm::DILocalScope>(getOrCreateScope(DS));
   assert(Scope && "variable has no local scope");
   auto Loc = getDebugLoc(*this, VarDecl);

   // FIXME: this should be the scope of the type's declaration.
   // If this is an argument, attach it to the current function scope.
   if (VarInfo.ArgNo > 0) {
      while (isa<llvm::DILexicalBlock>(Scope))
         Scope = cast<llvm::DILexicalBlock>(Scope)->getScope();
   }
   assert(Scope && isa<llvm::DIScope>(Scope) && "variable has no scope");
   llvm::DIFile *Unit = getFile(Scope);
   llvm::DIType *DITy = getOrCreateType(DbgTy);
   assert(DITy && "could not determine debug type of variable");
   if (VarInfo.Constant)
      DITy = DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_const_type, DITy);

   unsigned Line = Loc.Line;

   // Self is always an artificial argument, so are variables without location.
   if (!Line || (VarInfo.ArgNo > 0 && VarInfo.Name == IGM.Context.Id_self.str()))
      Artificial = ArtificialValue;

   llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
   if (Artificial || DITy->isArtificial() || DITy == InternalType)
      Flags |= llvm::DINode::FlagArtificial;

   // This could be Opts.Optimize if we would also unique DIVariables here.
   bool Optimized = false;
   // Create the descriptor for the variable.
   llvm::DILocalVariable *Var =
      (VarInfo.ArgNo > 0)
      ? DBuilder.createParameterVariable(Scope, VarInfo.Name, VarInfo.ArgNo,
                                         Unit, Line, DITy, Optimized, Flags)
      : DBuilder.createAutoVariable(Scope, VarInfo.Name, Unit, Line, DITy,
                                    Optimized, Flags);

   // Running variables for the current/previous piece.
   bool IsPiece = Storage.size() > 1;
   uint64_t SizeOfByte = CI.getTargetInfo().getCharWidth();
   unsigned AlignInBits = SizeOfByte;
   unsigned OffsetInBits = 0;
   unsigned SizeInBits = 0;

   for (llvm::Value *Piece : Storage) {
      SmallVector<uint64_t, 3> Operands;
      if (Indirection)
         Operands.push_back(llvm::dwarf::DW_OP_deref);

      if (IsPiece) {
         // Advance the offset and align it for the next piece.
         OffsetInBits += llvm::alignTo(SizeInBits, AlignInBits);
         SizeInBits = IGM.DataLayout.getTypeSizeInBits(Piece->getType());
         AlignInBits = IGM.DataLayout.getABITypeAlignment(Piece->getType());
         if (!AlignInBits)
            AlignInBits = SizeOfByte;

         // Sanity checks.
         assert(SizeInBits && "zero-sized piece");
         assert(SizeInBits < getSizeInBits(Var) && "piece covers entire var");
         assert(OffsetInBits + SizeInBits <= getSizeInBits(Var) && "pars > totum");

         // Add the piece DWARF expression.
         Operands.push_back(llvm::dwarf::DW_OP_LLVM_fragment);
         Operands.push_back(OffsetInBits);
         Operands.push_back(SizeInBits);
      }
      emitDbgIntrinsic(Builder, Piece, Var, DBuilder.createExpression(Operands),
                       Line, Loc.Column, Scope, DS);
   }

   // Emit locationless intrinsic for variables that were optimized away.
   if (Storage.empty())
      emitDbgIntrinsic(Builder, llvm::ConstantInt::get(IGM.Int64Ty, 0), Var,
                       DBuilder.createExpression(), Line, Loc.Column, Scope, DS);
}

void IRGenDebugInfoImpl::emitDbgIntrinsic(
   IRBuilder &Builder, llvm::Value *Storage, llvm::DILocalVariable *Var,
   llvm::DIExpression *Expr, unsigned Line, unsigned Col,
   llvm::DILocalScope *Scope, const PILDebugScope *DS) {
   // Set the location/scope of the intrinsic.
   auto *InlinedAt = createInlinedAt(DS);
   auto DL = llvm::DebugLoc::get(Line, Col, Scope, InlinedAt);
   auto *BB = Builder.GetInsertBlock();

   // An alloca may only be described by exactly one dbg.declare.
   if (isa<llvm::AllocaInst>(Storage) && !llvm::FindDbgAddrUses(Storage).empty())
      return;

   // A dbg.declare is only meaningful if there is a single alloca for
   // the variable that is live throughout the function.
   if (auto *Alloca = dyn_cast<llvm::AllocaInst>(Storage)) {
      auto *ParentBB = Alloca->getParent();
      auto InsertBefore = std::next(Alloca->getIterator());
      if (InsertBefore != ParentBB->end())
         DBuilder.insertDeclare(Alloca, Var, Expr, DL, &*InsertBefore);
      else
         DBuilder.insertDeclare(Alloca, Var, Expr, DL, ParentBB);
   } else if (isa<llvm::IntrinsicInst>(Storage) &&
              cast<llvm::IntrinsicInst>(Storage)->getIntrinsicID() ==
              llvm::Intrinsic::coro_alloca_get) {
      // FIXME: The live range of a coroutine alloca within the function may be
      // limited, so using a dbg.addr instead of a dbg.declare would be more
      // appropriate.
      DBuilder.insertDeclare(Storage, Var, Expr, DL, BB);
   } else {
      // Insert a dbg.value at the current insertion point.
      DBuilder.insertDbgValueIntrinsic(Storage, Var, Expr, DL, BB);
   }
}

void IRGenDebugInfoImpl::emitGlobalVariableDeclaration(
   llvm::GlobalVariable *Var, StringRef Name, StringRef LinkageName,
   DebugTypeInfo DbgTy, bool IsLocalToUnit, bool InFixedBuffer,
   Optional<PILLocation> Loc) {
   if (Opts.DebugInfoLevel <= IRGenDebugInfoLevel::LineTables)
      return;

   llvm::DIType *DITy = getOrCreateType(DbgTy);
   VarDecl *VD = nullptr;
   if (Loc)
      VD = dyn_cast_or_null<VarDecl>(Loc->getAsAstNode<Decl>());
   if (!VD || VD->isLet())
      DITy = DBuilder.createQualifiedType(llvm::dwarf::DW_TAG_const_type, DITy);

   if (DITy->isArtificial() || DITy == InternalType || !Loc)
      // FIXME: Really these should be marked as artificial, but LLVM
      // currently has no support for flags to be put on global
      // variables. In the mean time, elide these variables, they
      // would confuse both the user and LLDB.
      return;

   if (InFixedBuffer)
      DITy = createFixedValueBufferStruct(DITy);

   auto L = getStartLocation(Loc);
   auto File = getOrCreateFile(L.Filename);

   // Emit it as global variable of the current module.
   llvm::DIExpression *Expr = nullptr;
   if (!Var)
      Expr = DBuilder.createConstantValueExpression(0);
   auto *GV = DBuilder.createGlobalVariableExpression(
      MainModule, Name, LinkageName, File, L.Line, DITy, IsLocalToUnit, Expr);
   if (Var)
      Var->addDebugInfo(GV);
}

void IRGenDebugInfoImpl::emitTypeMetadata(IRGenFunction &IGF,
                                          llvm::Value *Metadata, unsigned Depth,
                                          unsigned Index,
                                          StringRef Name) {
   if (Opts.DebugInfoLevel <= IRGenDebugInfoLevel::LineTables)
      return;

   // Don't emit debug info in transparent functions.
   auto *DS = IGF.getDebugScope();
   if (!DS || DS->getInlinedFunction()->isTransparent())
      return;

   llvm::SmallString<8> Buf;
   static const char *Tau = u8"\u03C4";
   llvm::raw_svector_ostream OS(Buf);
   OS << '$' << Tau << '_' << Depth << '_' << Index;
   auto DbgTy = DebugTypeInfo::getArchetype(
      getMetadataType(Name)->getDeclaredInterfaceType().getPointer(),
      Metadata->getType(), Size(CI.getTargetInfo().getPointerWidth(0)),
      Alignment(CI.getTargetInfo().getPointerAlign(0)));
   emitVariableDeclaration(IGF.Builder, Metadata, DbgTy, IGF.getDebugScope(),
                           nullptr, {OS.str().str(), 0, false},
      // swift.type is already a pointer type,
      // having a shadow copy doesn't add another
      // layer of indirection.
                           DirectValue, ArtificialValue);
}

PILLocation::DebugLoc IRGenDebugInfoImpl::decodeSourceLoc(SourceLoc SL) {
   auto &Cached = DebugLocCache[SL.getOpaquePointerValue()];
   if (Cached.Filename.empty())
      Cached = sanitizeCodeViewDebugLoc(PILLocation::decode(SL, SM));
   return Cached;
}

} // anonymous namespace

std::unique_ptr<IRGenDebugInfo> IRGenDebugInfo::createIRGenDebugInfo(
   const IRGenOptions &Opts, ClangImporter &CI, IRGenModule &IGM,
   llvm::Module &M, StringRef MainOutputFilenameForDebugInfo) {
   return std::make_unique<IRGenDebugInfoImpl>(Opts, CI, IGM, M,
                                                MainOutputFilenameForDebugInfo);
}

IRGenDebugInfo::~IRGenDebugInfo() {}

// Forwarding to the private implementation.
void IRGenDebugInfo::finalize() {
   static_cast<IRGenDebugInfoImpl *>(this)->finalize();
}

void IRGenDebugInfo::setCurrentLoc(IRBuilder &Builder, const PILDebugScope *DS,
                                   PILLocation Loc) {
   static_cast<IRGenDebugInfoImpl *>(this)->setCurrentLoc(Builder, DS, Loc);
}

void IRGenDebugInfo::addFailureMessageToCurrentLoc(IRBuilder &Builder,
                                                   StringRef failureMsg) {
   static_cast<IRGenDebugInfoImpl *>(this)->
      addFailureMessageToCurrentLoc(Builder, failureMsg);
}

void IRGenDebugInfo::clearLoc(IRBuilder &Builder) {
   static_cast<IRGenDebugInfoImpl *>(this)->clearLoc(Builder);
}

void IRGenDebugInfo::pushLoc() {
   static_cast<IRGenDebugInfoImpl *>(this)->pushLoc();
}

void IRGenDebugInfo::popLoc() {
   static_cast<IRGenDebugInfoImpl *>(this)->popLoc();
}

void IRGenDebugInfo::setInlinedTrapLocation(IRBuilder &Builder,
                                            const PILDebugScope *Scope) {
   static_cast<IRGenDebugInfoImpl *>(this)->setInlinedTrapLocation(Builder,
                                                                   Scope);
}

void IRGenDebugInfo::setEntryPointLoc(IRBuilder &Builder) {
   static_cast<IRGenDebugInfoImpl *>(this)->setEntryPointLoc(Builder);
}

llvm::DIScope *IRGenDebugInfo::getEntryPointFn() {
   return static_cast<IRGenDebugInfoImpl *>(this)->getEntryPointFn();
}

llvm::DIScope *IRGenDebugInfo::getOrCreateScope(const PILDebugScope *DS) {
   return static_cast<IRGenDebugInfoImpl *>(this)->getOrCreateScope(DS);
}

void IRGenDebugInfo::emitImport(ImportDecl *D) {
   static_cast<IRGenDebugInfoImpl *>(this)->emitImport(D);
}

llvm::DISubprogram *
IRGenDebugInfo::emitFunction(const PILDebugScope *DS, llvm::Function *Fn,
                             PILFunctionTypeRepresentation Rep, PILType Ty,
                             DeclContext *DeclCtx,
                             GenericEnvironment *GE) {
   return static_cast<IRGenDebugInfoImpl *>(this)->emitFunction(DS, Fn, Rep, Ty,
                                                                DeclCtx);
}

llvm::DISubprogram *IRGenDebugInfo::emitFunction(PILFunction &PILFn,
                                                 llvm::Function *Fn) {
   return static_cast<IRGenDebugInfoImpl *>(this)->emitFunction(PILFn, Fn);
}

void IRGenDebugInfo::emitArtificialFunction(IRBuilder &Builder,
                                            llvm::Function *Fn,
                                            PILType PILTy) {
   static_cast<IRGenDebugInfoImpl *>(this)->emitArtificialFunction(Builder,
                                                                   Fn, PILTy);
}

void IRGenDebugInfo::emitVariableDeclaration(
   IRBuilder &Builder, ArrayRef<llvm::Value *> Storage, DebugTypeInfo Ty,
   const PILDebugScope *DS, ValueDecl *VarDecl, PILDebugVariable VarInfo,
   IndirectionKind Indirection, ArtificialKind Artificial) {
   static_cast<IRGenDebugInfoImpl *>(this)->emitVariableDeclaration(
      Builder, Storage, Ty, DS, VarDecl, VarInfo, Indirection, Artificial);
}

void IRGenDebugInfo::emitDbgIntrinsic(IRBuilder &Builder, llvm::Value *Storage,
                                      llvm::DILocalVariable *Var,
                                      llvm::DIExpression *Expr, unsigned Line,
                                      unsigned Col, llvm::DILocalScope *Scope,
                                      const PILDebugScope *DS) {
   static_cast<IRGenDebugInfoImpl *>(this)->emitDbgIntrinsic(
      Builder, Storage, Var, Expr, Line, Col, Scope, DS);
}

void IRGenDebugInfo::emitGlobalVariableDeclaration(
   llvm::GlobalVariable *Storage, StringRef Name, StringRef LinkageName,
   DebugTypeInfo DebugType, bool IsLocalToUnit, bool InFixedBuffer,
   Optional<PILLocation> Loc) {
   static_cast<IRGenDebugInfoImpl *>(this)->emitGlobalVariableDeclaration(
      Storage, Name, LinkageName, DebugType, IsLocalToUnit, InFixedBuffer, Loc);
}

void IRGenDebugInfo::emitTypeMetadata(IRGenFunction &IGF, llvm::Value *Metadata,
                                      unsigned Depth, unsigned Index,
                                      StringRef Name) {
   static_cast<IRGenDebugInfoImpl *>(this)->emitTypeMetadata(
      IGF, Metadata, Depth, Index, Name);
}

llvm::DIBuilder &IRGenDebugInfo::getBuilder() {
   return static_cast<IRGenDebugInfoImpl *>(this)->getBuilder();
}

PILLocation::DebugLoc IRGenDebugInfo::decodeSourceLoc(SourceLoc SL) {
   return static_cast<IRGenDebugInfoImpl *>(this)->decodeSourceLoc(SL);
}

AutoRestoreLocation::AutoRestoreLocation(IRGenDebugInfo *DI, IRBuilder &Builder)
   : DI(DI), Builder(Builder) {
   if (DI)
      SavedLocation = Builder.getCurrentDebugLocation();
}

/// Autorestore everything back to normal.
AutoRestoreLocation::~AutoRestoreLocation() {
   if (DI)
      Builder.SetCurrentDebugLocation(SavedLocation);
}

ArtificialLocation::ArtificialLocation(const PILDebugScope *DS,
                                       IRGenDebugInfo *DI, IRBuilder &Builder)
   : AutoRestoreLocation(DI, Builder) {
   if (DI) {
      unsigned Line = 0;
      auto *Scope = DI->getOrCreateScope(DS);
      if (static_cast<IRGenDebugInfoImpl *>(DI)->getDebugInfoFormat() ==
          IRGenDebugInfoFormat::CodeView) {
         // In CodeView, line zero is not an artificial line location and so we
         // try to use the location of the scope.
         if (auto *LB = dyn_cast<llvm::DILexicalBlock>(Scope))
            Line = LB->getLine();
         else if (auto *SP = dyn_cast<llvm::DISubprogram>(Scope))
            Line = SP->getLine();
      }
      auto DL = llvm::DebugLoc::get(Line, 0, Scope);
      Builder.SetCurrentDebugLocation(DL);
   }
}

PrologueLocation::PrologueLocation(IRGenDebugInfo *DI, IRBuilder &Builder)
   : AutoRestoreLocation(DI, Builder) {
   if (DI)
      DI->clearLoc(Builder);
}
